ObjectMapper是用Swift語言實現(xiàn)對象和JSON相互轉換的框架
ObjectMapper框架支持的數據結構類型:
- Int
- Bool
- Double
- Float
- String
- RawRepresentable(Enums)
- Array<AnyObject>
- 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是ObjectMapper框架中定義的一個接口
public protocol Mappable {
/// This function can be used to validate JSON prior to mapping.
/// Return nil to cancel mapping at this point
init?(_ map: Map)
/// This function is where all variable mappings should occur.
///It is executed by Mapper during the mapping (serialization and deserialization) process.
mutating func mapping(map: Map)
}
配置
- 在項目的podfile中添加:
pod 'ObjectMapper', '~> 1.3'
- 運行 pod install
案例
class User: Mappable {
var username: String?
var age: Int?
var weight: Double!
var array: [AnyObject]?
var dictionary: [String : AnyObject] = [:]
var bestFriend: User? // Nested User object
var friends: [User]? // Array of Users
var birthday: NSDate?
var imageURLs: Array<NSURL>?
required init?(_ map: Map) {
}
// Mappable
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())
posterURL <- (map["image"], URLTransform())
}
}
自定義的Model需要實現(xiàn)Mappable接口,并在mapping(map: Map)方法中將Model的屬性與JSON結構的Key相映射, 如果ObjectMapper支持該屬性的類型的轉換, 只需要寫
username <- map["username"]
如果ObjectMapper不支持轉換就需要調用Mappable額外提供的類, NSDate類型可以用DateTransform()類轉換:
birthday <- (map["birthday"], DateTransform())
如果ObjectMapper也沒有提供類型轉化方法就需要自定義了轉換類了, 這里就自定義了一個URLArrayTransform類:
import Foundation
import ObjectMapper
class URLArrayTransform: TransformType {
typealias Object = Array<NSURL>
typealias JSON = Array<AnyObject>
init() {}
func transformFromJSON(value: AnyObject?) -> Array<NSURL>? {
if let URLStrings = value as? [String] {
var listOfUrls = [NSURL]()
for item in URLStrings {
if let url = NSURL(string: item) {
listOfUrls.append(url)
}
}
return listOfUrls
}
return nil
}
func transformToJSON(value: [NSURL]?) -> JSON? {
if let urls = value {
var urlStrings = [String]()
for url in urls {
urlStrings.append(url.absoluteString)
}
return urlStrings
}
return nil
}
}
自定義的轉換類需要實現(xiàn) ObjectMapper 的 TransformType 接口, 從 URLArrayTransform 的實現(xiàn)中可以看出自定義轉換類還是比較簡單的, 主要就是重寫 transformFromJSON 和 transformToJSON 方法.
完整實現(xiàn)了 User 類后, 就可以是 User 和 JSON 字符串相互轉換了
let user = User(JSONString: JSONString)
let JSONString = user.toJSONString(prettyPrint: true) //prettyPrint參數用于生成JSON字符串是否格式化, 以便于打印
使用Mapper類轉換
let user = Mapper<User>().map(JSONString: JSONString)
let JSONString = Mapper().toJSONString(user, prettyPrint: true)
補充: AlamofireObjectMapper
tristanhimmelman/AlamofireObjectMapper
該框架可以結合 Alamofire 和 ObjectMapper 使用, 為Alamofire的Request類擴展出了responseObject 和 responseArray 方法, 更方便的將網絡通信返回的JSON數據轉換成對象
配置
- 在項目的podfile中添加:
pod 'AlamofireObjectMapper', '~> 3.0'
- 運行 pod install
案例
let URL = "..."
Alamofire.request(.GET, URL).responseObject { (response: DataResponse<WeatherResponse>) in
let weatherResponse = response.result.value
if let threeDayForecast = weatherResponse?.threeDayForecast {
for forecast in threeDayForecast {
print(forecast.day)
print(forecast.temperature)
}
}
}