Upgrade to Pro — share decks privately, control downloads, hide ads and more …

iOSConfSG 2017: Decoding Codable

Avatar for sammyd 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

Avatar for sammyd

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