Codables: (De)Serializing - Ch. 2: Coding Keys

Codables: (De)Serializing - Ch. 2: Coding Keys

CodingKeys are created to map data between your model and the data. These are mostly created as an enum to easily map the data in a custom decoding or encoding logic. If you don't declare the keys yourself, the compiler will do this automatically for you. But as we want to map data differently we will to this on our own now.

An object that defines the coding keys has to conform to the protocol CodingKey (no s). This has to have two initializers: One init?(intValue: Int) and `init?(stringValue: String)` with corresponding properties var intValue: Int? { get }? and var stringValue: String { get } (Apple Documentation). As you can see, stringValue is not optional. This is because the keys of a dictionary use strings in most cases or can be at least converted to a string. Arrays are automatically handled by iterating the data and don't require a coding key for each index.

The easiest way to conform to this protocol is to use an enum with a defined RawValue and this is what I'll use in my example.

This will be our input JSON for now:

{
    "id": "5A30CB22-76C8-4A2D-A86E-5AB181DD5838",
    "username": "CBeloch",
    "age": 30
}

Let's take our example from above and map id of the incoming data to our property called identifier.

struct User {
    let identifier: String
    let username: String
    let age: Int
}

// MARK: Codable

extension User: Codable {
    private enum CodingKeys: String, CodingKey {
        case identifier = "id"
        case username
        case age
    }
}

And thats it! The enum has a String as RawValue type and we set the value of the identifier case to `"id"`. The raw values for username and age are automatically generated, based on their name. The important part is, that the names for the keys have to match the property names and that you add a key for all of your properties.

You can restrict access to the CodingKeys by setting them to private so you can't access the keys from the outside by using User.CodingKeys.

In the next chapter I'll show you how to write your own decoder logic for your model which will be an initializer. In that chapter, naming of the CodingKeys enum and naming of the keys will not matter anymore.