Swift 5: JSON Parsing Made Easy – DzTechno


Learn one of the basics of iOS app development with easy and beginner-friendly examples

Learn Swift: Working with JSON
Image credit: Author

JSON stands for JavaScript Object Notation. It’s a popular text-based data format used everywhere for representing structured data. Almost every programming language supports it with Swift being no exception. You are going to use JSON a lot throughout your career, so make sure you don’t miss out!

In Swift, parsing JSON is common in almost every app. Luckily, working with JSON is easy in Swift. Better yet, it doesn’t require setting up any external dependencies.

An illustration of converting JSON to Swift

Let’s get started!

Let’s start off by working with some video data. For instance, let’s say you perform a network request to retrieve some videos from a website. As a response, you get a JSON object:

In your app, you want to convert this JSON to a Swift object. To do this, let’s store this JSON data in a structure.

To start off, let’s create a structure that conforms to the Decodable protocol to store all the listed properties found in the JSON data:

You can now parse the JSON data by using the above structure in conjunction with the built-in JSONDecoder():

That’s all there is to it. Congratulations — now you know the basics of JSON parsing in Swift.

Next, let’s go through some common use cases that you need to understand.

You are actually not required to define each property that comes with your JSON data. In the previous example, you could convert your JSON response to a Video object with this plain structure as well:

struct Video: Decodable {
let title: String
}

This way the decoder only parses the title from the JSON data and discards everything else.

Sometimes you may not be certain whether some property is returned or not. For example, imagine some of the videos have transcriptions and some don’t. To parse this data safely, you can define a property as optional and just let the JSONDecoder take care of the rest:

The program works regardless of whether or not thetranscription is missing in the data.

Most of the time, JSON data is not just one JSON object. Usually, an array of JSON objects is returned instead.

As an example, you could retrieve the videos of a channel with a request that returns the videos as a JSON array:

3 imaginary videos as JSON data retrieved from example.com’s video server

To parse this JSON array successfully, the only thing you need to change is to define the decodable type as [Video].self instead of Video.self highlighting that a JSON array is converted:

Just in case you missed anything, take a peek at the full code for this example.

You don’t always want to copy the JSON data using the exact same names. For example, you might want to change video’s title and name to category a topic respectively:

Change title and category from JSON data to name and topic respectively onSwift’s side.

To create a custom name mapping you need to modify the Video structure by adding a CodingKeys enum into it. In this enumeration you simply specify how you want to change the property names:

Call ‘title’ a ‘name’ and ‘category’ a ‘topic’ on Swift’s side.

Notice how you need to have all the keys present inside the CodingKeys enum—even those whose name remains the same.

In case you missed something, check out the full code here.

A common use case for changing the names of the properties is when converting the case.

For example, a JSON response could have a property number_of_views. However, in Swift, you would like to get rid of the underscores and capitalize separate words: numberOfViews.

You may already know that:

  • number_of_views is in what is called snake case
  • numberOfViews is in camel case

Swift also knows this so you don’t actually need to create a custom mapping yourself. Instead, you can configure the keyEncodingStrategy property of JSON decoder to .convertFromSnakeCase.

For instance, let’s say your JSON response looks like this:

Now to encode this data successfully, especially the number_of_views, you need to update the JSON decoder’s keyDecodingStrategy to .convertFromSnakeCase, which is simple:

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let jsonData = JSON.data(using: .utf8)!
let video: Video = try! decoder.decode(Video.self, from: jsonData)

If you missed something, check the full code for this part.

It is very common to encounter dates in JSON data, so it is worthwhile learning how to parse dates.

Dates in JSON are defined as a string or time interval. Similar to the previous example, you can set a strategy for the JSON decoder to handle parsing dates.

For instance, let’s say that this time your video’s JSON data looks like this:

{
"title": "JSON Made Simple",
"date": "2021-05-13T11:23:31Z"
}

Let’s create a Video structure to store this data:

struct BlogPost: Decodable {
let title: String
let date: Date
}

Keep in mind that in this case, the date follows the format: yyyy-MM-dd'T'HH:mm:ss. In order to correctly decode this date, you first need to create a custom DateFormatter object with this format:

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"

Then you define the dateDecodingStrategy of the JSON decoder and use the dateFormatter object with it:

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(dateFormatter)

Finally, you can decode the JSON data to a Video object and the date is parsed correctly:

let jsonData = JSON.data(using: .utf8)!
let video: Video = try! decoder.decode(Video.self, from: jsonData)
print(video.date)

Output:

2021-05-13T11:23:31Z

According to Apple, there are other date formatting strategies available too:

If you missed something, check the full code for this example.

Leave a Reply

Your email address will not be published. Required fields are marked *