Categories
Uncategorized

How to parse JSON in Swift 5

In this tutorial, we talk about a very important concept when it comes to working with APIs: How to parse JSON in Swift. We’ll talk about how to download JSON data from an URL and how to make use of it by encoding it. We learn all of this the easy way with using the Codable protocol!

What we want to achieve 🚀

Supposed we have an API that allows us to download images via their url’s and the usernames of the uploader, we want to create an app that displays that image with the according username. It should look similar to this:

The JSON data we use for this looks like this:

In this tutorial, we start with learning how to download the JSON data and how to parse it so we can extract the image URL’s and the usernames.

Creating the Swift data model for our JSON data 🛠

Take a look at the JSON data above. It contains three entries (001, 002, and 003), where each has one imageURL and one uploaderName. To parse the JSON, we first need to define suitable data models for storing the parsed data later on.

Our data model we start with is the one we use for the entries’ content, the image data. We use a struct containing an imageURL and uploaderName property for this.

struct Image: Codable {
    let imageURL: String
    let uploaderName: String
}

Our second data model is for the entries itself. The only property of this model is a dictionary, where the key is the name of the entry (e.g. 001) and the value an instance of our just created Image model.

struct Entry: Codable {
    let images: [String: Image]
}

You see that we needed to create two different “model layers”, just as our JSON data has two “layers”.

Tip: Especially when it comes to more complex JSON data, you can use a tool such as quicktype, which automatically creates data models out of your JSON, ready for being used in your Swift project.

Downloading the JSON data ⬇️

Now we are ready to download our JSON data. I uploaded my sample JSON data to the web using this free tool. You can do this too if you want and then use the generated URL for retrieving the data. In real life you would use the API url from now on.

We start with creating a Swift URL object out of our URL.

if let url = URL(string: "http://www.json-generator.com/api/json/get/cfpeTpOFrC?indent=2") {
    //
}

We can then retrieve the JSON data from the URL like this:

if let url = URL(string: "http://www.json-generator.com/api/json/get/cfpeTpOFrC?indent=2") {
   URLSession.shared.dataTask(with: url) { data, response, error in
    if let data = data {
        //...
       }
   }.resume()
}

Parsing the JSON data in Swift💡

To decode the JSON data we have to initialize a JSONDecoder.

if let url = URL(string: "http://www.json-generator.com/api/json/get/cfpeTpOFrC?indent=2") {
   URLSession.shared.dataTask(with: url) { data, response, error in
    if let data = data {
        let jsonDecoder = JSONDecoder()
       }
   }.resume()
}

We can now parse the JSON by using the Decoder and our created data models. We do this inside a try-catch block to print out the error when something goes wrong with the parsing process.

if let url = URL(string: "http://www.json-generator.com/api/json/get/cfpeTpOFrC?indent=2") {
   URLSession.shared.dataTask(with: url) { data, response, error in
    if let data = data {
        let jsonDecoder = JSONDecoder()
        do {
            let parsedJSON = try jsonDecoder.decode(Entry.self, from: data)
        } catch {
            print(error)
        }
       }
   }.resume()
}

At this point the parsedJSON property is assigned to an instance of our Entry class. This means that the parsedJSON contains a dictionary, where the values are instances of the Image class.

Therefore we can cycle through every Image instance of our Entry’s dictionary and grab the imageURL and uploaderName of each one.

if let url = URL(string: "http://www.json-generator.com/api/json/get/cfpeTpOFrC?indent=2") {
   URLSession.shared.dataTask(with: url) { data, response, error in
     if let data = data {
         let jsonDecoder = JSONDecoder()
         do {
             let parsedJSON = try jsonDecoder.decode(Entry.self, from: data)
             for image in parsedJSON.images {
                 print(image.value.imageURL)
                 print(image.value.uploaderName)
            }
        } catch {
            print(error)
        }
       }
   }.resume()
}

We could now use this data for downloading the images via the image URLs and displaying the according uploader user names. How to do this with SwiftUI is explained in our Mastering SwiftUI book where we use the Flickr API to parse image data from the user’s location.

Conclusion 🎊

Great, we just learned how to retrieve and parse JSON data from the web by using the Swift Codeable protocol and our own data models. You are now able to work with API’s that provide data via JSON.

I hope you enjoyed this tutorial! If you want to learn more about SwiftUI, make sure you check out our free SwiftUI Basics eBook and our other tutorials! Also make sure you follow us on Instagram and subscribe to our newsletter to not miss any updates, tutorials and tips about SwiftUI and more!