DEV Community

Jyothish Johnson
Jyothish Johnson

Posted on

JSON basics, encoding and decoding with Swift

This is a first part of a beginner series, where we understand basic of networking in Swift.

To simplify it greatly, JSON(Javascript Object Notation) is the way most clients and servers, share data with each other.

Here is a sample json, that fetches list of followers for a users profile:

{
  "userId": "123456",
  "userName": "John Doe",
  "followers": [
    {
      "followerId": "789012",
      "followerUsername": "follower1_username",
      "followerName": "Follower One"
    },
    {
      "followerId": "345678",
      "followerUsername": "follower2_username",
      "followerName": "Follower Two"
    },
    {
      "followerId": "901234",
      "followerUsername": "follower3_username",
      "followerName": "Follower Three"
    }
  ]
}

Enter fullscreen mode Exit fullscreen mode

JSON Decoding

One of the most basic things you will do as part of networking in Swift, is displaying the data received from server into some UI. Lets take the above JSON as an example. To do this we have to decode the JSON response into a object in Swift that we can reason about.

Firstly we will create a struct in Swift that can be mapped to the json response.

//1
struct User: Decodable {
    //2
    let userId: String
    let userName: String
    let followers: [Follower]

    struct Follower: Decodable {
        let followerId: String
        let followerUsername: String
        let followerName: String
    }
}
Enter fullscreen mode Exit fullscreen mode

Note: Here we are using exact same keys as in the json response. More about custom keys in a later article.

  1. The struct we created is confirming to Decodable protocol, which is required for the json to be decoded to a Swift object.
  2. If you notice, all the properties we used here have the same key with the json. This is important as the mapping happens between same keys(case-sensitive). Of-course we can customise the keys based on our needs, this will be covered in a later article.

Now lets write the code to decode this json.

//1
let json = """
{
  "userId": "123456",
  "userName": "John Doe",
  "followers": [
    {
      "followerId": "789012",
      "followerUsername": "follower1_username",
      "followerName": "Follower One"
    },
    {
      "followerId": "345678",
      "followerUsername": "follower2_username",
      "followerName": "Follower Two"
    },
    {
      "followerId": "901234",
      "followerUsername": "follower3_username",
      "followerName": "Follower Three"
    }
  ]
}
"""

//2
if let data = json.data(using: .utf8) {

    //3
    if let userObj = try? JSONDecoder().decode(User.self, from: data) {
        print(userObj)
    } else {
        print("Decoding failed")
    }
} else {
    print("Error getting json data")
}

Enter fullscreen mode Exit fullscreen mode
  1. We will use Swift's multiline string literals to store json into a property.
  2. This line converts the json string into a Data object where the characters of the string are encoded using UTF-8.
  3. This line uses the instance method of JSONDecoder to specify the type of the object(ie. User) that we want and passing the data for decoding.

Xcode console response for User object

Now we can see the User object being printed in Xcode console.

This can help you get started with displaying data received from your server.


JSON Encoding

Most of the times, we also have to send some or the other data back to the server. For example,

  • User searches something in your app
  • User authentication
  • Save user data to server

In the above cases, you will have to send some form of data as part of your httpBody. In these kind of scenarios we have to convert our Swift object to an encoded data. Lets look into how we can do that.

First things first, we have to update our User struct to be encodable. For this we have to conform to the Encodable protocol. But as we already have a conformance to Decodable, there is an easier way to do this: Codable

Codable is literally conbination of Encodable and Decodable protocols.

typealias Codable = Decodable & Encodable
Enter fullscreen mode Exit fullscreen mode

Updated User struct

struct User: Codable {
    let userId: String
    let userName: String
    let followers: [Follower]

    struct Follower: Codable {
        let followerId: String
        let followerUsername: String
        let followerName: String
    }
}
Enter fullscreen mode Exit fullscreen mode

Now lets see how to encode the User object.

func encode(user: User) {
    //1
    if let encodedData = try? JSONEncoder().encode(user) {
        //2
        if let jsonString = String(data: encodedData, encoding: .utf8) {
            print(jsonString)
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
  1. We pass the User object to be encoded to JSONEncoder's encode function. If encoding is successful we will get encoded Data, which we use based on our needs (ie. Send to server via the api, or print the encoded String as we do here)
  2. We pass the encoded data to String's initializer and print the json string which is returned. This json string is exactly same as the json that we created in the beginning.

Console response below πŸ‘‡
Xcode console response for encoded json string

Thats a wrap on basics of encoding and decoding json in Swift!

All the code available in Github gist


πŸ—¨οΈπŸ’‘ Join the Conversation! Share Your Thoughts Below.

πŸ—£οΈ Your opinion matters! Eager to hear your take on this topic. Don't hold backβ€”let's dive into a lively discussion!

Enjoyed this Article?

πŸ’– React: Click the heart icon to show your appreciation and help others discover this content too!

πŸ”” Follow for more Swift/iOS content! @jyo_johnson on X(Twitter)

πŸš€ Share: Spread the knowledge! Share this article with your network.

Your engagement is what keeps our community thriving. Thank you for being a part of it!

Top comments (0)