Hamid Hamid - 2 months ago 42
JSON Question

Swift 3 json parsing

I am running into troubles updating my app as Alamofire and SwiftyJSON are not yet supporting Swift 3. I have a url that would return me json as follows:

{
"products": [
{
"body_html":"",
"created_at":"2016-03-02T13:56:18+03:00",
"id":489759251,
"handle":"product",
"options":[
{
"id":627488838,
"product_id":489759251,
"name":"Title",
"position":1,
"values":[
"Default Title"
]
}
],

},

{
"body_html":"",
"created_at":"2016-03-08T05:17:55+03:00",
"id":530420915,
"handle":"product-2",
"options":[
{
"id":6319359750,
"product_id":530420915,
"name":"Title",
"position":1,
"values":[
"Default Title"
]
}
],

},
]
}


I need to be able to parse that json and list all returned products and be able to read any specific attribute and sub options of each.

I checked some other questions here and found several solutions and was able to get the json data and printed it as above. But, I couldn't parse it.

let shopUrl = "https://\(apiKey):\(password)@\(hostname)" + "/admin/products.json"

let url = URL(string: shopUrl)
URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in
if error != nil {
print(error)
} else {
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:Any]
print(json)
} catch let error as NSError {
print(error)
}
}
}).resume()


Any help?

Answer

To loop over all of the products you need to extract and cast it to the correct type. In this case an array of [String: Any].

I extracted the relevant bit of code and cleaned it up a bit to make this answer more readable.

guard let json = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any],
    let products = json["products"] as? [[String: Any]]
    else { return }

for product in products {
    guard let id = product["id"] as? Int,
        let options = product["options"] as? [[String: Any]]
        else { return }

    print(id)
    print(options)
}