Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

iOSConfSG 2017: Decoding Codable

sammyd
October 19, 2017

iOSConfSG 2017: Decoding Codable

A discussion on using Codable in Swift 4 for serialisation.

Code available at https://github.com/sammyd/iOSConfSG2017_Codable

sammyd

October 19, 2017
Tweet

More Decks by sammyd

Other Decks in Programming

Transcript

  1. serialisation is the process of translating data structures or object

    state into a format that can be stored or transmitted and reconstructed later. — Wikipedia, obvs
  2. JSON { "name": "2D Apple Games by Tutorials", "sku": "igt1",

    "image_url": "\/a725405c-a26a-4974-bcb0-d7fdef766f99.png", "url": "\/products\/2d-apple-games-by-tutorials" } Swift struct Product { let name: String let image_url: URL? let url: URL? let sku: String }
  3. Naïve Parsing1 var repos = [Repo]() if let json :

    AnyObject = json { if let array = json as? NSArray { for jsonItem in array as [AnyObject] { if let id = jsonItem.valueForKey("id") as? Int { if let name = jsonItem.valueForKey("name") as? String { if let url_string = jsonItem.valueForKey("url") as? String { if let fork = jsonItem.valueForKey("fork") as? Bool { if let url = NSURL(string: url_string) { let description = jsonItem.valueForKey("description") as? String var homepage: NSURL? = .None if let homepage_string = jsonItem.valueForKey("homepage") as? String { homepage = NSURL(string: homepage_string) } let repo = Repo(id: id, name: name, desc: description, url: url, homepage: homepage, fork: fork) repos += [repo] } } } } } } } } 1 This Swift is 2.5 years old
  4. SwiftyJSON2 let json = JSON(data: rawJSON!, options: .allZeros, error: nil)

    var repos = [Repo]() for (index: String, subJson: JSON) in json { if let id = subJson["id"].int, let name = subJson["name"].string, let url = subJson["url"].string, let fork = subJson["fork"].bool { var homepage: NSURL? = .None if let homepage_raw = subJson["homepage"].string { homepage = NSURL(string: homepage_raw) } let url_url = NSURL(string: url)! repos += [Repo(id: id, name: name, desc: subJson["description"].string, url: url_url, homepage: homepage, fork: fork)] } } 2 It's from a blog I wrote about different JSON parsing options in Swift.
  5. Argo3 extension Repo: JSONDecodable { static func create(id: Int)(name: String)(desc:

    String?) (url: NSURL)(homepage: NSURL?)(fork: Bool) -> Repo { return Repo(id: id, name: name, desc: desc, url: url, homepage: homepage, fork: fork) } static func decode(j: JSON) -> Repo? { return Repo.create <^> j <| "id" <*> j <| "name" <*> j <|? "description" <*> j <| "url" <*> j <|? "homepage" <*> j <| "fork" } } let repos: [Repo]? = (JSONValue.parse <^> json) >>- decodeArray 3 Don't use any of them. Read the blog here: http://blog.scottlogic.com/2015/03/09/json-in-swift.html.
  6. 1.

  7. 2.

  8. Encoder public protocol Encoder { .... public func container<Key>(keyedBy type:

    Key.Type) -> KeyedEncodingContainer<Key> where Key : CodingKey public func unkeyedContainer() -> UnkeyedEncodingContainer public func singleValueContainer() -> SingleValueEncodingContainer }
  9. Decoder public protocol Decoder { ... public func container<Key>(keyedBy type:

    Key.Type) throws -> KeyedDecodingContainer<Key> where Key : CodingKey public func unkeyedContainer() throws -> UnkeyedDecodingContainer public func singleValueContainer() throws -> SingleValueDecodingContainer }
  10. Some Links from Clever People — swiftunboxed.com/stdlib/json-encoder-encodable/ — swiftunboxed.com/stdlib/json-decoder-decodable/ —

    mikeash.com/pyblog/friday-qa-2017-07-14- swiftcodable.html — mikeash.com/pyblog/friday-qa-2017-07-28-a-binary- coder-for-swift.html — lists.swift.org/pipermail/swift-evolution/Week-of- Mon-20170731/038522.html