Working with JSON data and extracting relevant information from it can be frustrating. Consider the JSON response for our fetchRepos function:
[
{
"id": 68144965,
"name": "JSONNode",
"full_name": "keefmoon/JSONNode",
"owner": {
"login": "keefmoon",
"id": 271298,
"avatar_url": "https://avatars.githubusercontent.com/u/271298?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/keefmoon",
"html_url": "https://github.com/keefmoon",
"followers_url": "https://api.github.com/users/keefmoon/followers",
//... Some more URLs
"received_events_url":
"https://api.github.com/users/keefmoon/received_events",
"type": "User",
"site_admin": false
},
"private": false,
//... more values
}
//... more repositories
]
If we want to get the username for the owner of the first repository, we need to do the following:
let jsonData = //... returned from the network
guard
let deserialised = try? JSONSerialization.jsonObject(with: jsonData, options: []),
let repoArray = deserialised as? [[String: Any]],
let firstRepo = repoArray.first,
let ownerDictionary = firstRepo["owner"] as? [String: Any],
let username = ownerDictionary["login"] as? String
else {
return
}
print(username)
That's a lot of optional unwrapping and casting, just to get one value! Swift's strongly typed nature doesn't work well with JSON's loosely defined schema, which is why you have to do a lot of work to turn loosely-typed information into strongly-typed values.
To help with these problems, a number of open source frameworks are available, which make working with JSON in Swift easier. SwiftyJSON is a popular framework that can be found on GitHub at https://github.com/SwiftyJSON/SwiftyJSON.
I have also built a lightweight JSON helper called JSONNode, which can also be found on GitHub at https://github.com/keefmoon/JSONnode.
With JSONNode, you can perform the same task of retrieving the owner's username for the first repository, with the following code:
let jsonData = //... returned from the network
guard
let jsonNode = try? JSONNode(data: jsonData),
let username = jsonNode[0]["owner"]["username"].string
else {
return
}
print(username)
Information within JSON, of any depth, can be retrieved in one line using subscripts.
If you find JSONNode useful, let me know.