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:
- init(coder:) — Returns an object initialized from data in a given unarchiver.
- 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
- Encodable — for encoding
- Decodable — for decoding
- 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