Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Painless JSON Parsing With Swift Codable

DZone's Guide to

Painless JSON Parsing With Swift Codable

In this tutorial, you'll learn how to parse JSON using Swift 4 Codable, to be able to use your data when building your mobile apps.

· Mobile Zone ·
Free Resource

Recently, JSON has become the most widely used format to transfer data all over the internet. In the world of iOS development, it's very common for a developer to work with JSON data in Swift and use it for building iOS apps. There are some cool libraries like SwiftyJSON already available to work with JSON data in Swift and those libraries become popular because developers don't need to deal with an unreadable mess with JSONSerialization to parse JSON. Fortunately, Swift 4 has introduced amazing Codable protocol as part of Foundation framework and JSON parsing became a single or couple of lines of code. This solution is fully supported by Apple and can be easily adopted. It provides customization to encode and decode complex scenarios.

In this article, we will see how to parse JSON using Swift 4 Codable by building a Github Information app.

At WWDC 2017, Apple introduced a new feature in Swift to parse JSON without any pain using the Swift Codable protocol. There is a talk available to watch on Whats New in Foundation, where you can watch about this new featured from the 23-minute mark onwards. Basically, this protocol has a combination of Encodable and Decodable protocol that can be used to work with JSON data in both directions. In summary, Swift Codable protocol has offered following things to us.

  • Using Codable, we can model JSONObject or PropertyList file into equivalent Struct or Classes by writing very few lines of code. We don't have to write the constructor for the properties in the objects. It's all handed by Codable. We just need to extend our model to conform to the Codable, Decodable or Encodable protocol.
  • The mismatch between the strong data types of Swift and loose data types of JSON has been internally handled by Swift compiler. We can now handle Swift Data types like Date, URL, Float etc
  • Complex JSON can be modeled easily using Nesting Structs for readability.
  • Parsing actual JSON becomes a one-liner using JSONDecoder.

There are many articles already written on this topic to cover the end to end introduction of Codable protocol, but in this brief article, we will use the GitHub API and build a sample app to demonstrate this feature in brief.

We will use the very famous GitHub API to demonstrate this feature. We will build a simple app that takes a GitHub username and shows some information when we tap the "Show" button.

There is an API to display public information of GitHub Users, meaning I can find the details of my GitHub account by using this API endpoint:

https://api.github.com/users/shashikant86

This will return the information in JSON format which looks like this at the moment:

{
  "login": "Shashikant86",
  "id": 683799,
  "avatar_url": "https://avatars0.githubusercontent.com/u/683799?v=4",
  "gravatar_id": "",
  "url": "https://api.github.com/users/Shashikant86",
  "html_url": "https://github.com/Shashikant86",
  "followers_url": "https://api.github.com/users/Shashikant86/followers",
  "following_url": "https://api.github.com/users/Shashikant86/following{/other_user}",
  "gists_url": "https://api.github.com/users/Shashikant86/gists{/gist_id}",
  "starred_url": "https://api.github.com/users/Shashikant86/starred{/owner}{/repo}",
  "subscriptions_url": "https://api.github.com/users/Shashikant86/subscriptions",
  "organizations_url": "https://api.github.com/users/Shashikant86/orgs",
  "repos_url": "https://api.github.com/users/Shashikant86/repos",
  "events_url": "https://api.github.com/users/Shashikant86/events{/privacy}",
  "received_events_url": "https://api.github.com/users/Shashikant86/received_events",
  "type": "User",
  "site_admin": false,
  "name": "Shashikant",
  "company": "@AOL, @BBC, @PhotoBox",
  "blog": "http://shashikantjagtap.net",
  "location": "London",
  "email": null,
  "hireable": null,
  "bio": "Author of BDDfire & XCFit. DevOps Automation iOS Swift PHP Ruby Development. CI&CD[Jenkins, Docker, AWS, Xcode Server] BDD[Cucumber Behat Cucumberish, Fitnesse]",
  "public_repos": 112,
  "public_gists": 1,
  "followers": 108,
  "following": 52,
  "created_at": "2011-03-22T12:39:11Z",
  "updated_at": "2017-10-05T14:32:54Z"
}

This is actually a lot of information, but for the demo, we will only use the following properties:

  • name
  • avatar_url
  • location
  • followers
  • public_repos

Now that we have our endpoints, let's create a single View iOS Application in Xcode. We could use MVC, MVVM or similar pattern but we will do everything in the for this demo. We can easily model this information using simple Swift Struct like this:

struct MyGitHub {
    let name: String?
    let location: String?
    let followers: Int?
    let avatar_url: URL?
    let public_repo: Int?
}

I can probably go ahead and write ad constructor for each property and so on. However, I will stop myself at this stage as I already spotted the problems:

  1. The constant avatar_url is of the type URL, but in JSON, it’s String.
  2. Also, notice that constant is declared as camel case, which is not Swift standard convention.

Fortunately, Codable has an answer to both problems.

  • We have to make our Struct to conform to Codable protocol which will take care of Data Type Mismatch. The Swift compiler will take care of it under the hood. We don't need to write constructor as well.
  • In order to solve camel case problem, we can declare Coding Keys enum and tell to use snake case for Swift constant and camel case for JSON.

The resulting Struct will look like this:

struct MyGitHub: Codable {
 
    let name: String?
    let location: String?
    let followers: Int?
    let avatarUrl: URL?
    let repos: Int?
    
    private enum CodingKeys: String, CodingKey {
        case name
        case location
        case followers
        case repos = "public_repos"
        case avatarUrl = "avatar_url"
        
    }
}

Now that, we have achieved out snake casing for Swift and we also have Swift types in our model by conforming to Codable protocol.

Parsing JSON With JSONDecoder

Now we have our JSON endpoints and model based on the JSON, let's see how easy it is to parse this JSON. First, we will make the request to the endpoint and grab the JSON, and with a single line of code, we will parse the JSON using JSONDecoder.

guard let gitUrl = URL(string: "https://api.github.com/users/shashikant86") else { return }
   URLSession.shared.dataTask(with: gitUrl) { (data, response
            , error) in      
            guard let data = data else { return }
            do {
                let decoder = JSONDecoder()
                let gitData = try decoder.decode(MyGitHub.self, from: data)
                print(gitData.name)
                
            } catch let err {
                print("Err", err)
         }
   }.resume()

That's it! We have parsed out JSON with single or couple of lines of code. We can now print all the properties using the gitData object.

Preparing the UI for the App

Now that we have parsed out JSON and we can access all the properties that needed for our app, let's build a UI for the app to ask users to enter their GitHub username and press the "show" button. We will also put some labels to display this information in the UI.

Note: I am horrible in designing the UI so my crappy storyboard looks like this.

We will then link that UI element to ViewController to display specific information.

Source Code

The source code for this demo app is available on GitHub: Decodable-Swift4.

Just clone the repo and play with the code.

Have fun and enjoy Codable Protocol. Our app will look like this at the end:

Using Swift 4 and Codable protocol, it became very easy to parse any JSON with any complexity and use it in an iOS app. Thanks to the Foundation framework team for providing such a great feature embedded in Swift. It's your decision to convert all your models to use Codable protocol and probably retire the third-party framework that has been used to parse JSON from your iOS apps.

Topics:
mobile ,json ,swift ,swift codable ,xcode

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}