Convert Json string to Json object in Swift 4
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")
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]]
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.
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)
}