Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Protocol Oriented JSON Parsing in Swift

603 views

Published on

A Utah Valley Cocoaheads presentation I gave on JSON parsing in Swift in a protocol oriented style.

Published in: Mobile
  • Be the first to comment

Protocol Oriented JSON Parsing in Swift

  1. 1. JSON Parsing by JaSON Larsen @jarsen
  2. 2. JSON Parsing by JaSON Larsen @jarsen
  3. 3. JSONValue Extraction by JaSON Larsen @jarsen
  4. 4. The History
  5. 5. Inthe beginning... if let id = json["id"] as? Int { if let name = json["name"] as? String { if let email = json["email"] as? String { // create user } } }
  6. 6. Swift 1.2 if let id = json["id"] as? Int, name = json["name"] as? String, email = json["email"] as? String { // create user } else { // return some error, ex: `Result<T>` }
  7. 7. Swift 2 guard let id = json["id"] as? Int, name = json["name"] as? String, email = json["email"] as? String { // throw some error } // create user
  8. 8. Argo extension User: Decodable { static func decode(j: JSON) -> Decoded<User> { return curry(User.init) // used to have to make a separate `make` function <^> j <| "id" <*> j <| "name" <*> j <|? "email" // Use ? for parsing optional values <*> j <| "role" // Custom types that also conform to Decodable just work <*> j <| ["company", "name"] // Parse nested objects <*> j <|| "friends" // parse arrays of objects } } (https://github.com/thoughtbot/Argo)
  9. 9. WhatYouThink
  10. 10. WhatYourTeam Thinks
  11. 11. JSONArrays... var pets = [Pet]() if let petsObjects = json["pets"] as? [JSONObject] { for petObject in petsObjects { guard let id = petObject["id"] as? Int, name = petObject["name"] as? String else { continue // or throw error if less tolerant } let pet = Pet(id: id, name: name) pets.append(pet) } }
  12. 12. Whyso muchwork?
  13. 13. Wouldn'titbe greatif... struct User : JSONObjectConvertible { let id: Int let name: String let email: String? let pets: [Pet] init(json: JSONObject) throws { id = try json.valueForKey("id") name = try json.valueForKey("name") email = try json.valueForKey("email") pets = try json.valueForKey("pets") } }
  14. 14. The Implementation
  15. 15. Playground Gist https://gist.github.com/jarsen/672aa5969689c5864cac
  16. 16. Caveat: Core DataModels For NSManagedObject subclasses JSONObjectConvertible won't really work because init is not so simple... public protocol JSONDecoding { func update(json: JSONObject) throws }
  17. 17. Caveat: Core DataModels class User: NSManagedObject, JSONDecoding { @NSManaged var name: String @NSManaged var email: String func update(json: JSONObject) throws { try name = json.valueForKey("name") try email = json.valueForKey("email") } }
  18. 18. MatthewCheok'sJSONCodable extension User: JSONEncodable { func toJSON() throws -> AnyObject { return try JSONEncoder.create({ (encoder) -> Void in try encoder.encode(id, key: "id") try encoder.encode(name, key: "full_name") try encoder.encode(email, key: "email") try encoder.encode(company, key: "company") try encoder.encode(friends, key: "friends") }) } } (https://github.com/matthewcheok/JSONCodable)
  19. 19. SpecialThanks » Bart Whiteley » Brian Mullen » BJ Homer » Derrick Hathaway » Dave DeLong » Mark Schultz » Tim Shadel
  20. 20. Resources » My blog jasonlarsen.me (look for No-Magic JSON series) » JaSON https://github.com/jarsen/JaSON » JaSON (extension on Dictionary) https:// github.com/bwhiteley/JaSON

×