Codable in 10 minutes or less

Dimitri James Tsiflitzis

CocoaHeads

In the old days...

As we are all aware, to support encoding and decoding of instances in iOS, a class must adopt the NSCoding protocol and implement its methods:

  1. init(coder:) — Returns an object initialized from data in a given unarchiver.
  2. encode(with:) — Encodes the receiver using a given archiver.

 

Plenty of copy paste

In the old days...

class City: NSObject, NSCoding
{
    var name: String?
    var id: Int?
    
    required init?(coder aDecoder: NSCoder)
    {
        self.name = aDecoder.decodeObject(forKey: "name") as? String
        self.id = aDecoder.decodeObject(forKey: "id") as? Int
    }
    
    func encode(with aCoder: NSCoder)
    {
        aCoder.encode(self.name, forKey: "name")
        aCoder.encode(self.id, forKey: "id")
    }
}

Codable

Make your data types encodable and decodable for compatibility with external representations such as JSON.

Codable

  1. Encodable — for encoding
  2. Decodable — for decoding
  3. Codable — for both encoding as well as decoding

Encodable

A type that can encode itself to an external representation. It is used by the types that can be encoded.

It contains a single method:

encode(to:) — Encodes this value into the given encoder.

Decodable

A type that can decode itself from an external representation. It is used by the types that can be decoded.

It also contains a single method:

init(from:) — Creates a new instance by decoding from the given decoder.

Codable

A type that can convert itself into and out of an external representation. It is used by the type can be both encoded as well as decoded.

typealias Codable = Decodable & Encodable

Codable

struct Photo: Codable
{
    //String, URL, Bool and Date conform to Codable.
    var title: String
    var url: URL
    var isSample: Bool
    
    //The Dictionary is of type [String:String] and String already conforms to Codable.
    var metaData: [String:String]
    
    //PhotoType and Size are also Codable types
    var type: PhotoType
    var size: Size
}

struct Size: Codable
{
    var height: Double
    var width: Double
}

enum PhotoType: String, Codable
{
    case flower
    case animal
    case fruit
    case vegetable
}

Encoding — JSONEncoder

let photoObject = Photo(title: "Hibiscus", 
url: URL(string: "https://www.flowers.com/hibiscus")!, 
isSample: false, metaData: ["color" : "red"],
 type: .flower, size: Size(width: 200, height: 200))

let encodedData = try? JSONEncoder().encode(photoObject)

Decoding — JSONDecoder

let jsonString = """
{
    "type":"fruit",
    "size":{
               "width":150,
               "height":150
           },
    "title":"Apple",
    "url":"https:\\/\\/www.fruits.com\\/apple",
    "isSample":true,
    "metaData":{
                  "color":"green"
               }
}
"""
if let jsonData = jsonString.data(using: .utf8)
{
    let photoObject = try? JSONDecoder().decode(Photo.self, from: jsonData)
}

Choosing Properties to Encode and Decode — CodingKeys

Codable types can declare a special nested enumeration named CodingKeys that conforms to the CodingKey protocol. When this enumeration is present, its cases serve as the authoritative list of properties that must be included when instances of a codable type are encoded or decoded.

Choosing Properties to Encode and Decode — CodingKeys

struct Photo: Codable
{
    //...Other properties (described in Code Snippet - 1)...
    
    //This property is not included in the CodingKeys enum and hence will not be encoded/decoded.
    var format: String = "png"
    
    enum CodingKeys: String, CodingKey
    {
        case title = "name"
        case url = "link"
        case isSample
        case metaData
        case type
        case size
    }
}

Let's code

Ευχαριστούμε

 

 

🥃

Copy of Machine Learning with Core ML

By tsif

Copy of Machine Learning with Core ML

  • 146