Reputation: 975
I am receiving a response something like this in some key eg:
"abc" : "[{\"ischeck\":true,\"type\":\"Some type\"},{\"ischeck\":false,\"type\":\"other type\"}]"]"
I need to convert this into normal array. i am using this following function for this.
[{"ischeck": true, "type":"Some type"},{"ischeck": true, "type":"other type"}]
func fromJSON(string: String) throws -> [[String: Any]] {
let data = string.data(using: .utf8)!
guard let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) as? [AnyObject] else {
throw NSError(domain: NSCocoaErrorDomain, code: 1, userInfo: [NSLocalizedDescriptionKey: "Invalid JSON"])
}
//swiftlint:disable:next force_cast
return jsonObject.map { $0 as! [String: Any] }
}
Upvotes: 1
Views: 367
Reputation: 285079
You have to call JSONSerialization.jsonObject
twice. First to deserialize the root object and then to deserialize the JSON string for key abc
.
func fromJSON(string: String) throws -> [[String: Any]] {
let data = Data(string.utf8)
guard let rootObject = try JSONSerialization.jsonObject(with: data) as? [String:String],
let innerJSON = rootObject["abc"] else {
throw NSError(domain: NSCocoaErrorDomain, code: 1, userInfo: [NSLocalizedDescriptionKey: "Invalid JSON"])
}
let innerData = Data(innerJSON.utf8)
guard let innerObject = try JSONSerialization.jsonObject(with: innerData) as? [[String:Any]] else {
throw NSError(domain: NSCocoaErrorDomain, code: 1, userInfo: [NSLocalizedDescriptionKey: "Invalid JSON"])
}
return innerObject
}
Another more comfortable approach is to decode the string with Decodable
let jsonString = """
{"abc":"[{\\"ischeck\\":true,\\"type\\":\\"Some type\\"},{\\"ischeck\\":false,\\"type\\":\\"other type\\"}]"}
"""
struct Root : Decodable {
let abc : [Item]
private enum CodingKeys : String, CodingKey { case abc }
init(from decoder : Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let abcString = try container.decode(String.self, forKey: .abc)
abc = try JSONDecoder().decode([Item].self, from: Data(abcString.utf8))
}
}
struct Item : Decodable {
let ischeck : Bool
let type : String
}
do {
let result = try JSONDecoder().decode(Root.self, from: Data(jsonString.utf8))
print(result.abc)
} catch {
print(error)
}
Upvotes: 1