How to decode JSON in Swift. All you need to know.
JSON is one of the most common data formats for transferring data between servers and devices. Parsing JSON in Swift is a common task to do because almost every app uses JSON to present data in one or the other way. Let's learn everything you need to know about it.
How to decode JSON in Swift.
- Fetch JSON data using a network request or open a local file.
- Make sure your model types conform to the Decodable protocol.
- Pass the data to the JSONDecoder instance using created Decodable models.
Let's dive in.
Decode JSON in Swift using Decodable protocol.
Let's take a look at how to decode JSON data in Swift using JSONDecoder. Here is the simplified 'user' response from Github Rest API.
{
"login": "octocat",
"id": 1,
"url": "https://api.github.com/users/octocat",
"email": "octocat@github.com",
"plan": {
"name": "Medium",
"space": 400,
"private_repos": 20,
"collaborators": 0
}
}
We can decode that data by creating the following structure, that conforms to the Decodable protocol:
struct User: Decodable {
let login: String
let id: Int
let url: String
let email: String
let plan: UserPlan
}
struct UserPlan: Decodable {
let name: String
let space: Int
let private_repos: Int
let collaborators: Int
}
We defined two structures that conform to the Decodable protocol and used a custom-defined Decodable type UserPlan as a plan property in the 'User' structure. This is possible because every type that conforms to the Decodable protocol will be automatically converted.
Now we can use the JSONDecoder instance to map user JSON data into our freshly created model:
let user = try! JSONDecoder().decode(User.self, from: data)
That's it. We decoded JSON data using JSONDecoder into our model.
Custom property names
In the sample above we made all the properties match the names of keys from JSON. If you like to define different property names, you can create mapping by defining a custom CodingKeys enum inside of the desired model structure.
In the previous example, we could name private_repos property as privateRepos:
struct UserPlan: Decodable {
let name: String
let space: Int
let privateRepos: Int
let collaborators: Int
enum CodingKeys: String, CodingKey {
case name, space, collaborators
// Map the JSON key "private_repos" to the Swift property name "privateRepos"
case privateRepos = "private_repos"
}
}
For this special case, you could also avoid defining the CodingKeys and use the .convertFromSnakeCase strategy of JSONDecoder instead:
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let user = try! decoder.decode(User.self, from: data)
Edge cases
- It is not necessary to define each property
- Use optional if you are not sure whether a JSON key is mandatory or not.
Decode JSON Arrays in Swift.
Decoding a JSON array is just as simple as decoding a single JSON object.
Let's consider we have an array of users like this:
[{
"login": "octocat",
"id": 1,
"url": "https://api.github.com/users/octocat",
"email": "octocat@github.com",
"plan": {
"name": "Medium",
"space": 400,
"private_repos": 20,
"collaborators": 0
}
},
{
"login": "tortilla",
"id": 2,
"url": "https://api.github.com/users/tortilla",
"email": "tortilla@github.com",
"plan": {
"name": "Medium",
"space": 213,
"private_repos": 3,
"collaborators": 12
}
}]
Swift Decodable protocol makes decoding JSON data in Swift easy.