Encoding and Decoding

https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types

Converting your instances to another representation, like a string or a stream of bytes. This process is known as encoding, also known as serialization.

The reverse process of turning the data into an instance is called decoding, or deserialization.

Imagine you have an instance you want to write to a file. The instance itself cannot be written as-is to the file, so you need to encode it into another representation, like as a stream of bytes: ![](/assets/encode.pn

Once the data is encoded and saved to a file, you can turn it back into an instance whenever you want by using a decoder: ![](/assets/encode.pn

Automatic Encoding and Decoding

If you want your type to be codable, the simplest way to do it is by conforming to Codable and making sure all its stored properties are also codable.

struct Employee: Codable {
    var name: String
    var id: Int
}

Encoding and Decoding Custom Types

JSON stands for JavaScript Object Notation, and is one of the most popular ways to serialize data. It’s easily readable by humans and easy for computers to parse and generate.

JSONEncoder and JSONDecoder

do {
    // Encode object to data
    let jsonEncoder = JSONEncoder()
    let jsonData = try jsonEncoder.encode(employee1)

    // Convert json data to string
    let jsonStr = String(data: jsonData, encoding: .utf8)

    // Decode data to object
    let jsonDecoder = JSONDecoder()
    let employee2 = try jsonDecoder.decode(Employee.self, from: jsonData)
} catch {
    debugPrint(error.localizedDescription)
}

Note that you need to tell the decoder what type to decode the JSON to, because the compiler can’t figure this out on its own.

Renaming Properties With CodingKeys

CodingKey Protocol, CodingKeys Enum

The CodingKeys enum, which conforms to CodingKey protocol, lets you rename specific properties in case the serialized format doesn’t match the requirements of the API.

struct Employee: Codable {
    var name: String
    var id: Int
    var favoriteToy: Toy

    enum CodingKeys: String, CodingKey {
        case id = "employeeId"
        case name
        case favoriteToy
    }
}

There are several things to note here:

  1. CodingKeys is a nested enumeration in your type.
  2. It has to conform to CodingKey.
  3. You also need String as the raw type, since the keys are always strings.
  4. You have to include all properties in the enumeration, even if you don’t plan to rename them.
  5. By default, this enumeration is created by the compiler, but when you need to rename a key you need to implement it yourself.

Manual Encoding and Decoding

extension Employee {
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        name = try values.decode(String.self, forKey: .name)
        id = try values.decode(Int.self, forKey: .id)
        let gift = try values.decode(String.self, forKey: .gift)
        favoriteToy = Toy(name: gift)
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(name, forKey: .name)
        try container.encode(id, forKey: .id)
        try container.encode(favoriteToy.name, forKey: .gift)
    }
}

results matching ""

    No results matching ""