ObjectMapper 简单使用

来源:互联网 发布:win7 linux双系统bios 编辑:程序博客网 时间:2024/06/05 10:58

ObjectMapper是啥?

ObjectMapper 是一个在 Swift 下数据转模型的非常好用,并且很 Swift 的一个框架。以前我们在写 OC 代码的时候用 MJExtension 转模型,到了 Swift 的时代赶紧将 ObjectMapper 使用起来吧。

用CocoaPods集成

首先当然要将这个库导入到自己项目里,在写 Swift 代码时,强力推荐用 CocoaPods 管理第三方框架,这样的好处很多的。第一就是方便,不易出错,节省时间。第二也是最重要的一点,Swift 当中采用了 命名空间 概念,简单来说就是 即使类型命名相同,只要来自不同的命名空间,就可以和平共处 。所以在 Swift 中使用 CocoaPods 的好处是显而易见的,CocoaPods 会自己生成一个新的工程 Pods ,一般来说命名空间的名字就是你的工程名。这样别人写的三方框架就和你自己的工程分割开来,当使用框架的时候就不怕遇到自己写的方法名和框架的方法名重复这样蛋疼的问题。

如何使用?

ObjectMapper 使用起来相当简单。首先创建自己的模型类,然后倒入头文件

import ObjectMapper

下一步采纳 ObjectMapper 的协议 Mappable

class Statuses: Mappable {}

进入头文件会看到 Mappable 必须要实现两个协议方法,和一个构造器:

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)    /// This is an optional function that can be used to:    ///        1) provide an existing cached object to be used for mapping    ///        2) return an object of another class (which conforms to Mappable) to be used for mapping. For instance, you may inspect the JSON to infer the type of object that should be used for any given mapping    static func objectForMapping(map: Map) -> Mappable?}

意思就是采纳这个协议的类,必须实现 Mappable 这个 protocol 中所指定的非可选的所有东西。下面搞起来:
在模型类的下面实现协议方法:

required init?(_ map: Map) {}func mapping(map: Map) {}

(知识补充: 在类中是无需标注mutating关键字的,mutating 只针对值类型,如枚举结构体
上面的代码中并没有实现 Mappable 中所指定的 static func objectForMapping(map: Map) -> Mappable? 这个类方法,是这样的,再次进入头文件会发现 Mappable 协议下面存在一个 Mappable 的协议扩展,我截取了其中的一部分:

public extension Mappable {    public static func objectForMapping(map: Map) -> Mappable? {        return nil    }        ......}

这个扩展中已经帮我们默认实现objectForMapping方法,所有不需要使用者实现这个方法,当然这个方法也是联想不出来的。

现在所有准备工作已经就绪,我的数据是这样的:

{    "statuses": [        {            "created_at": "Tue May 31 17:46:55 +0800 2011",            "id": 11488058246,            "text": "求关注。",            "source": "<a href="http://weibo.com" rel="nofollow">新浪微博</a>",            "user": {                "id": 1404376560,                "name": "zaku",                "description": "人生五十年,乃如梦如幻;有生斯有死,壮士复何憾。",            }        },        ...    ],    ...}

很简单 statuses 对应一个数组(tableView数据源),数组当中存放着很多个字典,字典中的数据就是需要展示在 tableView 上的数据,在已经创建好的 Statuses 类中,写上需要的属性:

class Statuses: Mappable {     var created_at: String? //字符串写成可选的     var id: Int = 0  //基本数据类型要赋个初值     var text: String?     var source: String?     var user: ??}

写到这里会发现当前的模型数据中又存在另一个模型数据 user,同样创建一个 User。同样是采纳协议,实现协议方法,创建属性:

class Users: Mappable {    var id: Int = 0    var name: String?    var description: String?}

补全整个模型的代码是这样的:

class Statuses: Mappable {     var created_at: String? //字符串写成可选的     var id: Int = 0  //基本数据类型要赋个初值     var text: String?     var source: String?     var user: Users?    required init?(_ map: Map) {    }    func mapping(map: Map) {    } }class Users: Mappable {    var id: Int = 0    var name: String?    var description: String?    required init?(_ map: Map) {    }    func mapping(map: Map) {    }}

好了,属性写完了,如何转换成模型呢?
Statuses 类中找到 func mapping(map: Map) 这个方法,在里面实现如下代码:

func mapping(map: Map) {        created_at <- map["created_at"]        id <- map["id"]        text <- map["text"]        source <- map["source"]        user <- map["user"]    }

同样的在 Users 类中也要做同样的事情:

func mapping(map: Map) {       id <- map["id"]       name <- map["name"]       description  <- map["description"]      }

很形象,通过 <- 符号可以清晰的表述出将某一个 key 中的 value 取出来,赋值给这个键对应的属性。其实 <- 是一个泛型函数,只不过长得有点奇怪

public func <- <T>(inout left: T?, right: Map) {    switch right.mappingType {    case .FromJSON where right.isKeyPresent:        FromJSON.optionalBasicType(&left, object: right.value())    case .ToJSON:        ToJSON.optionalBasicType(left, map: right)    default: ()    }}

到现在为止,所有的准备工作做完了,回头想想无非就是采纳协议,实现协议方法,就这么简单。好了,下面只要执行一句代码,轻轻松松转成模型。

let modelArr = Mapper<Statuses>().mapArray(/*把你的模型数据放进来*/)

此时 modelArr 的类型是这样的 [Statuses]? 一个存放了 Statuses 类型的数组。搞定,放在 cell 上显示一下吧。
最后补充:
既然能转成模型,同样也可以转成 JSON,同样一句代码:

let statusJson = status.toJSON()

statusJson 的类型是 [String: AnyObject]

结语

ObjectMapper 是一个 Swift 下很好的 数据转模型 框架。不推荐在 Swift 下使用 MJExtension ,虽然最后的效果是一样的,MJExtension基于运行时实现,Swift 为了和 OC 兼容,所有 继承自 NSObject 的类都可以使用运行时。如果单单创建一个 Swift 类运行时是无效果的。所以为了让代码更 Swift ,推荐使用 ObjectMapper
如有错误欢迎留言指正。



作者:LSYoung
链接:http://www.jianshu.com/p/3e999c40491a
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
原创粉丝点击