the last guide to parsing json you will ever need

20
jensravens.com / swift.berlin #25 The Last Guide To Parsing JSON You Will Ever Need Jens Ravens

Upload: jens-ravens

Post on 17-Mar-2018

211 views

Category:

Internet


0 download

TRANSCRIPT

Page 1: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

The Last Guide To Parsing JSON You Will Ever Need

Jens Ravens

Page 2: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

Who is this guy?

Page 3: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

Who is this guy?(aka the shameless self promotion part)

Page 4: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

Jens Ravens

Developer at nerdgeschoss, a mobile first dev agency for sophisticated software. We help startups and medium businesses to build awesome stuff.

Page 5: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

Jens Ravens

50% iOS / macOS using Swift 50% Web / API using Ruby on Rails

Page 6: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

Jens Ravens

Also I blog about Swift stuff on jensravens.com and organize the monthly swift.berlin meetup.

Page 7: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

The classical approach.

let json = """ { "id": 1, "name": "swift.berlin", "language_name": "swift", "host": { "name": "Flixbus" } }"""..data(using: .Encoding.utf8)!

struct Host { var name: String static func from(_ dict: [String:Any]) throws -> Host}

struct Meetup { var name: String var language: String var host: Host}

Page 8: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

The classical approach.

struct Host { var name: String static func from(_ dict: [String:Any]) throws -> Host}

Page 9: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

The classical approach.

struct Host { var name: String static func from(_ dict: [String:Any]) throws -> Host{ if let name = dict["name"] as? String { return Host(name: name) } throw ParseError.MissingKey }}

Page 10: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

The classical approach.struct Meetup { var name: String var language: String var host: Host static func from(_ dict: [String:Any]) throws -> Meetup { if let name = dict["name"] as? String, let language = dict["language_name"] as? String, let hostValues = dict["host"] as? [String:Any] { return Meetup(name: name, language: language, host: try Host.from(hostValues)) } throw ParseError.MissingKey }}

Page 11: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

The classical approach.

let dict = try! JSONSerialization.jsonObject(with: json, options: []) as! [String:Any]let meetup = try! Meetup.from(dict)

Page 12: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

The new Decodable//: The hosting company, now conforming to `Decodable`.struct Host: Decodable { var name: String}

//: The actual meetup, now conforming to `Decodable`.struct Meetup: Decodable { var name: String var language_name: String var host: Host}

let meetup = try! JSONDecoder().decode(Meetup.self, from: json)

Page 13: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

The new Decodable//: The hosting company, now conforming to `Decodable`.struct Host: Decodable { var name: String}

//: The actual meetup, now conforming to `Decodable`.struct Meetup: Decodable { var name: String var language_name: String var host: Host}

let meetup = try! JSONDecoder().decode(Meetup.self, from: json)

😱

Page 14: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

The new Decodable

//: The actual meetup, now conforming to `Decodable`.struct Meetup: Decodable { var name: String var language: String var host: Host

private enum CodingKeys: String, CodingKey { case name, language = "language_name", host }}

Page 15: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

Encoding Datastruct Host: Encodable { var name: String} struct Meetup: Encodable { var name: String var language: String var host: Host private enum CodingKeys: String, CodingKey { case name, language = "language_name", host }} let meetup = Meetup(name: "swift.berlin", language: "swift", host: Host(name: "Flixbus"))let json: String = try! JSONEncoder().encode(meetup)

Page 16: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

Encoding and Decoding

typealias Codable = Encodable & Decodable

Page 17: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

Additional Notes

• JSONDecoder has settings for Date and Data • Encoders for JSON, Property Lists, Custom Encoders • Protocols can be implemented manually • Compatible with NSCoding via NSKeyedArchiver

Page 18: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

Tips and Tricks

• avoid mixing business logic and JSON parsing • put API logic into a (separate) framework • your client models don’t have to match server models!

• this goes well with code generated api clients like swagger • there’s an extension for alamofire • encoding also works as an easy persistence mechanism

Page 19: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

More Ressources

What’s new in Foundation (WWDC 2017) https://developer.apple.com/videos/play/wwdc2017/212/

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

Swift Evolution https://github.com/apple/swift-evolution/blob/master/proposals/0167-swift-encoders.md

Page 20: The Last Guide To Parsing JSON You Will Ever Need

jensravens.com / swift.berlin #25

Thank you.

Jens Ravens / @jensravens