[Swift学习笔记] ObjectMapper 框架

Hearst-DD/ObjectMapper

ObjectMapper是用Swift语言实现对象和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需要实现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
    }
}

自定义的转换类需要实现 ObjectMapper 的 TransformType 接口, 从 URLArrayTransform 的实现中可以看出自定义转换类还是比较简单的, 主要就是重写 transformFromJSON 和 transformToJSON 方法.

完整实现了 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)           
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 今天在微博上看到了这句挺逗逼的句子,于是脑海浮现了这副画面,一位提刀的侠客骑着马路过一棵松树下,问了一位正在松树下...
    荣大叔阅读 932评论 0 1
  • 方法来源 本文所介绍的学习方法主要的观点来自《如何阅读一本书》、《软技能:代码之外的生存指南》和《把时间当做朋友》...
    EA88阅读 762评论 0 2