user1828605 user1828605 - 2 months ago 49
JSON Question

Parsing JSON using Swift 3

I have this json data that I want to consume in Swift 3. I'm learning Swift and building a very basic app that displays the list of items in tableUIView from JSON.

{
"expertPainPanels" : [
{
"name": "User A",
"organization": "Company A"
},
{
"name": "User B",
"organization": "Company B"
}
]
}


I'm trying to get this data using Swift 3.

if (statusCode == 200) {
do{
let json = try? JSONSerialization.jsonObject(with: data!, options:.allowFragments) // [[String:AnyObject]]

/*
If I do this:

let json = try? JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! [String:Any]

if let experts = json?["expertPainPanels"] as! [String: Any] {
I get "Initializer for conditional binding must have Optional type, not '[String: Any]'"

*/


// Type 'Any' has no subscript members.
if let experts = json["expertPainPanels"] as? [String: AnyObject] {

for expert in experts {
let name = expert["name"] as? String
let organization = expert["organization"] as? String
let expertPainPanel = ExpertPainPanel(name: name, organization: organization)!
self.expertPainPanels += [expertPainPanel]
self.tableView.reloadData()
self.removeLoadingScreen()
}
}
}catch {
print("Error with Json: \(error)")
}
}


It was working fine in Swift 2. I updated to Swift 3 which broke the code. I read several SO, but I still have hard time understanding it. I applied some suggestions including JSON Parsing in Swift 3, but I'm still unable to fix the error I'm getting.

Answer

As of Swift 3, you need to do a cast early on.

This line:

let json = try? JSONSerialization.jsonObject(with: data!, options:.allowFragments)

Should become this:

let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as? [String : AnyObject]

This is because JSONSerialization now returns Any, which does not implement a variation for the [] operator. Make sure you safely unwrap the cast and take the common measures to ensure you don't crash your program.

Edit: Your code should more or less look like this.

let data = Data()
let json = try JSONSerialization.jsonObject(with: data, options:.allowFragments) as! [String : AnyObject]
if let experts = json["expertPainPanels"] as? [String: AnyObject] {