ObjectMapper是swift写的框架,旨在简化模型(Struct/Class)和JSON相互转换.
ObjectMapper-GitHub 官方指南
Features
- 将JSON映射成对象
- 将对象映射成JSON
- 模型嵌套(模型可以在数组/字典中)
- 支持映射时候key的转换
- 支持结构体类型
基本使用
为了支持映射,class
或者sturct
只需要实现 Mapple
协议.
public protocol Mappable {
init?(_ map: Map)
mutating func mapping(map: Map)
}
public protocol MappableCluster: Mappable {
static func objectForMapping(map: Map) -> Mappable? //可选的方法
}
ObjectMapper使用<-
来定义每个成员变量是如何映射到JSON或者从JSON映射的
struct Temperature: Mappable {
var celsius: String?
var fahrenheit: String?
init?(_ map: Map) {
}
mutating func mapping(map: Map) {
celsius <- map["celsius"]
fahrenheit <- map["fahrenheit"]
}
}
一旦你的类实现Mappable
, 就可以方便实现模型和JSONh的相互转换
let user = Mapper<User>().map(JSONString)
将模型转换成JSON字符串:
let JSONString = Mapper().toJSONString(user, prettyPrint: true)
ObjectMapper支持的类型如下:
- Int
- Bool
- Double
- Float
- String
- RawRepresentable (Enums)
- Array
- Dictionary<String, AnyObject>
- Object<T: Mappable>
- Array<T: Mappable>
- Array<Array<T: Mappable>>
- Set<T: Mappable>
- Dictionary<String, T: Mappable>
- Dictionary<String, Array<T: Mappable>>
- Optionals of all the above
- Implicitly Unwrapped Optionals of the above
Mappable
协议
init?(_ map: Map) {...}
方法
这个可失败构造器,可以基于模型属性序列化的优先级来对JSON验证. 如下:必须保证name
有值才使初始化成功
required init?(_ map: Map){
// check if a required "name" property exists within the JSON.
if map["name"].value() == nil {
return nil
}
if map.JSONDictionary["name"] == nil {
return nil
}
}
mutating func mapping(map: Map)
方法
当 JSON -> 模型 时,初始化成功后会执行.
当 模型 -> JOSN 时,这是模型只会执行这个方法.
这是个可选的方法.如果实现这个方法 ,那么init?(_ map: Map)
就不再执行. 这个方法的作用在于:
- 提供一个存在的对象缓存用于mapping
- 返回一个其他类型的对象(也需遵循Mappale协议),例如:你可以观察JSON去推断应该用哪种类型来进行映射. 举例
class Vehicle: Mappable {
var type: String?
class func objectForMapping(map: Map) -> Mappable? {
if let type: String = map["type"].value() {
switch type {
case "car":
return Car(map)
case "bus":
return Bus(map)
default:
return nil
}
}
return nil
}
required init?(_ map: Map){
}
func mapping(map: Map) {
type <- map["type"]
}
}
类型嵌套映射 (Nested Objects)
如:
"distance" : {
"text" : "102 ft",
"value" : 31
}
处理方法:
func mapping(map: Map) {
distance <- map["distance.value"]
}
Nested keys 也支持访问数组里的值:
"distance" : [
{
"text" : "102 ft",
"value" : 31
}
]
处理方法:
func mapping(map: Map) {
distance <- map["distances.0.value"]
}
需要注意:如果你 json 的 key 包含了.
,你需要进行单独处理
func mapping(map: Map) {
identifier <- map["app.identifier", nested: false]
}
ObjectMapper 支持map中的常用的转换. 想实现转换,只需要创建个元组-> (map["filed_name"], transform())
birthday <- (map["birthday"], DateTransform())
上边的转换会使得JSON中的Int类型 与 NSDate 类型 相互转换.
当然我们可以实现自己的 custom transforms , 通过满足 TransformType
协议.
public protocol TransformType {
typealias Object
typealias JSON
func transformFromJSON(value: AnyObject?) -> Object?
func transformToJSON(value: Object?) -> JSON?
}
很多情况用TransformOf
类,能快速实现Transform
功能 . TransformOf
let transform = TransformOf<Int, String>(fromJSON: { (value: String?) -> Int? in
// transform value from String? to Int?
return Int(value!)
}, toJSON: { (value: Int?) -> String? in
// transform value from Int? to String?
if let value = value {
return String(value)
}
return nil
})
id <- (map["id"], transform)
更简单的写法
id <- (map["id"], TransformOf<Int, String>(fromJSON: { Int($0!) }, toJSON: { $0.map { String($0) } }))
举例: 我可以将JSON中的Int, Float等转成字符串.
let transformAnyObject = TransformOf<String, AnyObject>(fromJSON: { (value: AnyObject?) -> String? in
if let value = value {
return "\(value)"
}
return nil
}, toJSON: { (value: String?) -> AnyObject? in
if let value = value {
return value
}
return nil
})
fahrenheit <- (map["fahrenheit"], transformAnyObject) //map["fahrenheit"]
子类
实现Mappable
协议的类可以很容易被继承 .
class Base: Mappable {
var base: String?
required init?(_ map: Map) {
}
func mapping(map: Map) {
base <- map["base"]
}
}
class Subclass: Base {
var sub: String?
required init?(_ map: Map) {
super.init(map)
}
override func mapping(map: Map) {
super.mapping(map)
sub <- map["sub"]
}
}
不要忘记实现协议的初始化方法.
支持泛型 Generic Objects
ObjectMapper 支持泛型, 同样我们需要实现协议`Mappabl``` swift
class Result<T: Mappable>: Mappable {
var result: T?
required init?(_ map: Map){
}
func mapping(map: Map) {
result <- map["result"]
}
}
let result = Mapper<Result<User>>().SON)
更多
ObjectMapper-GitHub 官方文档