Mastering JSON Parsing in Swift with Codable

Simplifying JSON Parsing in Swift with Codable

Understanding JSON

JSON (JavaScript Object Notation) is a lightweight data-interchange format that’s easy for developers to read and write and simple for machines to parse and generate. JSON can be categorized into two different structures:

  • A collection of name/value pairs, for example:

{
  "first_name": "Rudrank",
  "last_name": "Riyam"
}
  • An ordered list of values as an array, for example:

{
  "qualifications": [
    {
      "name": "high_school",
      "passed": true
    },
    {
      "name": "bachelors",
      "passed": true
    },
    {
      "name": "masters",
      "passed": false
    }
  ]
}

Swift Protocols for Decoding and Encoding Data

Swift offers several protocols to help us change the way data is represented.

Decodable Protocol

Decodable is a type that can decode itself from an external representation. Here’s a simple JSON example:


struct Information: Decodable {
  let firstName: String
  let lastName: String
}

Encodable Protocol

Encodable is a type that can encode itself to an external representation. Using the example above, we can use the same structure and conform to the Encodable protocol to encode an object of Information into a JSON:


struct Information: Encodable {
  let firstName: String
  let lastName: String
}

Codable Protocol

Codable is a typealias for Decodable and Encodable protocols, meaning it provides a new name to an existing type. Codable is a type that can convert itself into and out of an external representation, where the representation is JSON or a similar format.

JSONDecoder Class

The JSONDecoder class decodes instances of a data type from JSON objects. The data type must conform to the Decodable protocol; it can be either predefined types like String, Double, or Date or custom classes, enumerations, or structures.

JSONEncoder Class

We use JSONEncoder to encode, rather than decode, instances of a data type as JSON objects. With this class, we primarily use the encode(_:) method that has the following definition:


func encode<T>(_ value: T) throws -> Data where T : Encodable

Practical Use Cases

Here are some practical use cases for simplifying JSON parsing in Swift using the Codable protocol.

Basic Example

Let’s start with a simple example that contains only one JSON object. If we search for suggestions using the Apple Music API, we get the following response:


{
  "kind": "terms",
  "searchTerm": "Apple",
  "displayTerm": "Apple"
}

Creating a struct for this object is simple. We require the properties kind, searchTerm, and displayTerm that are of the type String:


struct Suggestion: Codable {
  let kind: String
  let searchTerm: String
  let displayTerm: String
}

Nested Example

Decoding a single JSON object is easy, but what if a key contains an object of its own, like a nested structure? To address this scenario, we’ll create another struct for the nested object, and the key property will be the type of that object.


{
  "data": [
    {
      "id": "123",
      "attributes": {
        "name": "John Doe",
        "age": 30
      }
    }
  ]
}

We can create two different structs, one for the main object and one for the nested object:


struct User: Codable {
  let id: String
  let attributes: Attributes
}

struct Attributes: Codable {
  let name: String
  let age: Int
}

Array Example

The JSON response may contain many different objects, but it could also contain an array of objects. Let’s go back to the simple example where we have a Suggestion struct and extend it to an array of suggestions:


{
  "suggestions": [
    {
      "kind": "terms",
      "searchTerm": "Apple",
      "displayTerm": "Apple"
    },
    {
      "kind": "terms",
      "searchTerm": "Banana",
      "displayTerm": "Banana"
    }
  ]
}

We can create a property of the type [Suggestion]:


struct Suggestions: Codable {
  let suggestions: [Suggestion]
}

Leave a Reply