90

I try to convert JSON string to a JSON object but after JSONSerialization the output is nil in JSON.

Response String:

[{\"form_id\":3465,\"canonical_name\":\"df_SAWERQ\",\"form_name\":\"Activity 4 with Images\",\"form_desc\":null}]

I try to convert this string with my code below:

let jsonString = response.result.value
let data: Data? = jsonString?.data(using: .utf8)
let json = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String:AnyObject]
 print(json ?? "Empty Data")
LinusGeffarth
  • 27,197
  • 29
  • 120
  • 174
Inderpal Singh
  • 1,229
  • 2
  • 10
  • 13
  • did you added the alamofire pod. https://www.google.com/search?ei=968KWufnFcvWvgS7rKW4BA&q=alamofire+swift+4&oq=alamofire&gs_l=psy-ab.1.2.0i71k1l4.0.0.0.19859.0.0.0.0.0.0.0.0..0.0....0...1..64.psy-ab..0.0.0....0.w_2p_WJHPH4 – Arun Nov 14 '17 at 08:57
  • Yes I installed Alamofire Pod – Inderpal Singh Nov 14 '17 at 08:59
  • Use a `do ... catch` instead and print the error. It'll probably tell you what's wrong. – JeremyP Nov 14 '17 at 09:32

5 Answers5

135

The problem is that you thought your jsonString is a dictionary. It's not.

It's an array of dictionaries. In raw json strings, arrays begin with [ and dictionaries begin with {.


I used your json string with below code :

let string = "[{\"form_id\":3465,\"canonical_name\":\"df_SAWERQ\",\"form_name\":\"Activity 4 with Images\",\"form_desc\":null}]"
let data = string.data(using: .utf8)!
do {
    if let jsonArray = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? [Dictionary<String,Any>]
    {
       print(jsonArray) // use the json here     
    } else {
        print("bad json")
    }
} catch let error as NSError {
    print(error)
}

and I am getting the output :

[["form_desc": <null>, "form_name": Activity 4 with Images, "canonical_name": df_SAWERQ, "form_id": 3465]]
mfaani
  • 33,269
  • 19
  • 164
  • 293
Amit
  • 4,837
  • 5
  • 31
  • 46
  • How we get the value from "jsonArray". I am trying if let name = jsonArray["name"] as? String { // no error } which is giving the error "Cannot subscript a value of type '[Dictionary]' with an index of type 'String'" – Android is everything for me May 02 '18 at 11:16
  • 2
    @Androidiseverythingforme : That's an array of dictionary, try `let form_name = jsonArray[0]["form_name"] as? String` and you will get the output. – Amit May 02 '18 at 12:22
  • this was the solution for me too , i was getting a raw json from url , and was unable to read it as an array because it was a string; so the line : " let data = string.data(using: .utf8)! " mentionned in this solution was what solved it , Thank you sir – Taoufik Jun 09 '22 at 10:47
40

Using JSONSerialization always felt unSwifty and unwieldy, but it is even more so with the arrival of Codable in Swift 4. If you wield a [String:Any] in front of a simple struct it will ... hurt. Check out this in a Playground:

import Cocoa

let data = "[{\"form_id\":3465,\"canonical_name\":\"df_SAWERQ\",\"form_name\":\"Activity 4 with Images\",\"form_desc\":null}]".data(using: .utf8)!

struct Form: Codable {
    let id: Int
    let name: String
    let description: String?

    private enum CodingKeys: String, CodingKey {
        case id = "form_id"
        case name = "form_name"
        case description = "form_desc"
    }
}

do {
    let f = try JSONDecoder().decode([Form].self, from: data)
    print(f)
    print(f[0])
} catch {
    print(error)
}

With minimal effort handling this will feel a whole lot more comfortable. And you are given a lot more information if your JSON does not parse properly.

Patru
  • 4,481
  • 2
  • 32
  • 42
16

I tried the solutions here, and as? [String:AnyObject] worked for me:

do{
    if let json = stringToParse.data(using: String.Encoding.utf8){
        if let jsonData = try JSONSerialization.jsonObject(with: json, options: .allowFragments) as? [String:AnyObject]{
            let id = jsonData["id"] as! String
            ...
        }
    }
}catch {
    print(error.localizedDescription)

}
Zain Ul Abideen
  • 693
  • 10
  • 15
Aviram Netanel
  • 12,633
  • 9
  • 45
  • 69
7

I used below code and it's working fine for me. :

let jsonText = "{\"userName\":\"Bhavsang\"}"
var dictonary:NSDictionary?
    
if let data = jsonText.dataUsingEncoding(NSUTF8StringEncoding) {
        
     do {
            dictonary =  try NSJSONSerialization.JSONObjectWithData(data, options: [.allowFragments]) as? [String:AnyObject]
        
            if let myDictionary = dictonary
              {
                  print(" User name is: \(myDictionary["userName"]!)")
              }
            } catch let error as NSError {
            
            print(error)
         }
}
Dohab
  • 439
  • 5
  • 15
Bhavsang Jam
  • 374
  • 4
  • 12
-1
static func getJSONStringFromObject(object: Any?) -> String? {
    do {
        let jsonData = try JSONSerialization.data(withJSONObject: object ?? DUMMY_STRING, options: [])
        return String(data: jsonData, encoding: .utf8) ?? DUMMY_STRING
    } catch {
        print(error.localizedDescription)
    }
    return DUMMY_STRING
}
Divyansh Jain
  • 373
  • 2
  • 5