Upload
john-sundell
View
467
Download
0
Embed Size (px)
Citation preview
SWIFT & JSONJohn Sundell
Lead iOS Developer, Spotify
@johnsundellSWIFT
SWIFT =❤
SWIFT =+ JSON "
struct User { let name: String let age: Int }
{ "name": "John", "age": 28 }
func userFromData(data: NSData) throws -> User { let object = try NSJSONSerialization.JSONObjectWithData(data, options: []) guard let dictionary = object as? [String : AnyObject] else { throw JSONError.InvalidJSONObject } guard let name = dictionary["name"] as? String else { throw JSONError.InvalidValueForKey("name") } guard let age = dictionary["age"] as? Int else { throw JSONError.InvalidValueForKey("age") } return User(name: name, age: age) }
NOT REUSABLE
TO THE GITHUB MOBILE!
let json = JSON(data: data)
guard let name = json["name"].string else { throw JSONError.InvalidJSONObject }
guard let age = json["age"].string else { throw JSONError.InvalidJSONObject }
return User(name: name, age: age)
extension User: Decodable { static func decode(j: JSON) -> Decoded<User> { return curry(User.init) <^> j <| "id" <*> j <| "name" <*> j <|? "email" <*> j <| "role" <*> j <| ["company", "name"] <*> j <|| “friends" } }
class User: Mappable { var username: String? var age: Int? var weight: Double! var array: [AnyObject]? var dictionary: [String : AnyObject] = [:] var bestFriend: User? var friends: [User]? var birthday: NSDate? required init?(_ map: Map) {} func mapping(map: Map) { username <- map["username"] age <- map["age"] weight <- map["weight"] array <- map["arr"] dictionary <- map["dict"] bestFriend <- map["best_friend"] friends <- map["friends"] birthday <- (map["birthday"], DateTransform()) } }
EASY TO WRITE EASY TO READ
CLEAN MODEL CODE
UNBOXTHE EASY TO USE SWIFT JSON DECODER
struct User let name: String let age: Int
}
{: Unboxable
init(unboxer: Unboxer) { self.name = unboxer.unbox("name") self.age = unboxer.unbox("age") }
let user: User = try Unbox(data)
TYPE INFERENCE
METHOD OVERLOADING
class Unboxer {func unbox(key: String) -> Stringfunc unbox(key: String) -> Intfunc unbox(key: String) -> Double
func unbox(key: String) -> String?func unbox(key: String) -> Int?func unbox(key: String) -> Double?
... } ... }
struct User let name: String let age: Int
}
{: Unboxable
init(unboxer: Unboxer) { self.name = unboxer.unbox("name") self.age = unboxer.unbox("age") }
?
UNBOXER HOLDS STATE SO THAT OUR MODELS DON’T HAVE TO.
DEMO
TRANSFORMATIONS
CUSTOM UNBOXING API
ARRAY UNBOXINGALLOWING INVALID
COLLECTION ELEMENTS
CUSTOMIZED WRAPPING
PROPERTY TO KEY MAPPINGUNBOXABLE KEYS
DATE & URL SUPPORT
CONTEXTUAL OBJECTS
WRAPPABLE KEYS
SUNDELL.CO/UNBOX
SUNDELL.CO/WRAP
@JOHNSUNDELL