XMapping provides some useful functions for fetching field from JSON and perfroming transformation.
whole logic depends on swift generic and try-catch. with these two powerful thing, handle json can also be easy.
Mapper is provided as a wrapper for a JSON object. We all know JSON object can be a Dictionary, an Array, Number, String, Bool and Null,
and no one said a root JSON object should be a Dictionary, which means we should check type from root till we get what we want.
when getting something from JSON, we actually mean two step:
- get a
raw fieldat specifiedkeyPath. araw fieldis a raw JSON type value,keyPathis the path describing how to get the desired field. notice that, thiskeyPathis not the same as KVC's keyPath which uses.for key separation.keyPathin XMapping is an array containingStringorInt. - transfrom the
raw fieldto desired Type(String, Double, Date, URL .etc) transform is a function that receives araw fieldvalue, makes some magic and returns the desired result.
thanks to the well generic and try catch in swift, check type and report error become very easy.
someone would say why not just use Codable? if you really try, you will give up. Codable is too simple to fit complicated business logic.
say you have a struct Person, and want be initialized from a JSON:
public struct Person: ModelMappable { // Models should confirm to ModelMappable
public let id: Int
public let name: String
public let avatar: URL?
public let birthday: Date?
public let friends: [Person]
init(mapper: Mapper) throws {
id = try mapper.map("id")
name = try mapper.map("user_name")
avatar = try mapper.optionalMap("avatar_url")
birthday = try mapper.optionalMap("birthday", transform: Date.transformString) // some free util functions
friends = try mapper.optionalMap("friends") ?? []
}
}no magic here. Let's talk deeper.
id and name are required fields, so use map, corresponding keyPath is String "id", String "user_name" respectively.
avatar is optional, so use optionalMap. optionalMap tries to get a String value at avatar_url, and then uses URL.transform function to transform the string to URL.
birthday is almost the same as avatar, but a transform function is provides directly.
friends is an array of Person, we consider using empty array instead of [Person]?.
to be done...