Mapper is a simple Swift library to convert JSON to strongly typed objects. One advantage to Mapper over some other libraries is you can have immutable properties.
With CocoaPods
use_frameworks!pod"ModelMapper"With Carthage
github "lyft/mapper"
import Mapper
// Conform to the Mappable protocol
structUser:Mappable{letid:StringletphotoURL:URL?
// Implement this initializer
init(map:Mapper)throws{try id = map.from("id")
photoURL = map.optionalFrom("avatar_url")}}
// Create a user!
letJSON:NSDictionary=...letuser=User.from(JSON) // This is a 'User?'enumUserType:String{case Normal ="normal"case Admin ="admin"}structUser:Mappable{letid:Stringlettype:UserTypeinit(map:Mapper)throws{try id = map.from("id")try type = map.from("user_type")}}structUser:Mappable{letid:Stringletname:Stringinit(map:Mapper)throws{try id = map.from("id")try name = map.from("name")}}structGroup:Mappable{letid:Stringletusers:[User]init(map:Mapper)throws{try id = map.from("id")
users = map.optionalFrom("users")??[]}}extensionCLLocationCoordinate2D:Convertible{publicstaticfunc fromMap(_ value:Any)throws->CLLocationCoordinate2D{guardlet location = value as?NSDictionary,let latitude =location["lat"]as?Double,let longitude =location["lng"]as?Doubleelse{throwMapperError.convertibleError(value: value, type:[String:Double].self)}returnCLLocationCoordinate2D(latitude: latitude, longitude: longitude)}}structPlace:Mappable{letname:Stringletlocation:CLLocationCoordinate2Dinit(map:Mapper)throws{try name = map.from("name")try location = map.from("location")}}letJSON:NSDictionary=["name":"Lyft HQ","location":["lat":37.7603392,"lng":-122.41267249999999,],]letplace=Place.from(JSON)privatefunc extractFirstName(object:Any?)throws->String{guardlet fullName = object as?Stringelse{throwMapperError.convertibleError(value: object, type:String.self)}letparts= fullName.characters.split{ $0 ==""}.map(String.init)iflet firstName = parts.first {return firstName
}throwMapperError.customError(field:nil, message:"Couldn't split the string!")}structUser:Mappable{letfirstName:Stringinit(map:Mapper)throws{try firstName = map.from("name", transformation: extractFirstName)}}structUser:Mappable{letname:StringletJSON:AnyObjectinit(map:Mapper)throws{
// Access the 'first' key nested in a 'name' dictionary
try name = map.from("name.first")
// Access the original JSON (maybe for use with a transformation)
try JSON = map.from("")}}See the docstrings and tests for more information and examples.
These radars have affected the current implementation of Mapper
- rdar://23376350 Protocol extensions with initializers do not work in extensions
- rdar://23358609 Protocol extensions with initializers do not play well with classes
- rdar://23226135 Can't conform to protocols with similar generic function signatures
- rdar://23147654 Generic functions are not differentiated by their ability to throw
- rdar://23695200
Using the
??operator many times is unsustainable. - rdar://23697280 Lazy collection elements can be evaluated multiple times.
- rdar://23718307
Non final class with protocol extensions returning
Selfdon't work
Mapper is maintained by Lyft and released under the Apache 2.0 license. See LICENSE for details