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
  • Object
  • Array
  • Array>
  • Set
  • Dictionary
  • Dictionary>
  • 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 时,这是模型只会执行这个方法.

static func objectForMapping(map: Map) -> Mappable?方法

这是个可选的方法.如果实现这个方法 ,那么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]
}

常用的转换 Custom Transforms

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

很多情况用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 官方文档