到了 Swift 年代,第三方库 SwiftyJSON 和 ObjectMapper 都曾经作为 JSON 转换的中流砥柱,只是这两者还是免不了“手动指定字段和JSON字典映射关系”的工作。于是阿里想了个黑科技(HandyJSON),通过分析Swift数据结构在内存中的布局,自动分析出映射关系,进一步降低开发者使用的成本。
如今我们就有多个选择:ObjectMapper、HandyJSON、SwiftyJSON、MJExtension 等
其实我们在日常开发中,对于 JSON 数据的处理有两大需求:
- json 和 model 互相转换(Android Studio有 Gson format 插件,但Xcode没有类似功能)
- 服务端返回的 json 里可能有 null,但是 Swift 语言的空是用 nil 表示,需要空值处理(对象 Optional 类型)
框架简介
ObjectMapper
先看 ObjectMapper : Model 类必须实现 Mappable 协议,即实现 init 和 mapping 函数;适合跟 Alamofire 配合。但是 mapping 函数实现起来过于臃肿耗时,只能借助插件来快速完成。
1 | import ObjectMapper |
j2s 是一个 macOS app 能够将 JSON 对象转成 Swift 结构体
HandyJSON
再看 HandyJSON, 写起来比较方便,类和结构体要求继承于 HandyJSON、枚举要继承于 HandyJSONEnum。
1 | import HandyJSON |
比ObjectMapper使用上要简单, 不用写mapping函数那么多代码了。
SwiftyJSON
看 SwiftyJSON:取字段值使用比较方便, 但是然并卵? SwiftyJSON 不支持转 Model,如果你只是想要解析某几个字段,那么 SwiftyJSON 是不二选择, 而且适用于 Alamofire。
1 | let jsonString: String = "{\"username\":\"yuhanle\",\"age\":18,\"weight\":65.4,\"sex\":1,\"location\":\"Toronto, Canada\",\"three_day_forecast\":[{\"conditions\":\"Partly cloudy\",\"day\":\"Monday\",\"temperature\":20},{\"conditions\":\"Showers\",\"day\":\"Tuesday\",\"temperature\":22},{\"conditions\":\"Sunny\",\"day\":\"Wednesday\",\"temperature\":28}]}" |
MJExtension
最后看下一下 MJExtension,作为一个从 ObjC 年代就开始流程的转换框架,在如今使用的人仍然很多,但是对于 Swift 的集成却不是特别友好,官方 issue 列表中经常都会有申请支持 swift 的呼声!
1 | import MJExtension |
尽管在支持上不是特别友好,但是在自定义 Model 的过程中,应该是最轻松的一款,但是在升级 Swift 4 之后,需要在属性前添加 @objc 才可以正常使用,否则转换失败。具体情况可参考:Swift 4 字典转模型失败
另外还有一种情况,就是关于整型属性,需要给定初试值,也就是说,MJExtension 无法序列化/反序列化整型。解决办法很简单, 就是赋个默认值, 即将Optional整型变为整型就可以。
1 | class People: NSObject { |
运行耗时
我们准备了一小段 JSON 数据,循环解析 10000 次,来分析几大框架的运行耗时:
1 | { |
以 HandyJSON 为例,在开始处理数据和结束时,记录时间差,时间差的结果每次会有波动
1 | let maxCount = 10000 |
最终记录得到的结果对比图
测试项 | JSON -> MODEL | MODEL -> JSON |
---|---|---|
HandyJSON | 3.0839329957962 | 4.97446703910828 |
ObjeceMapper | 1.40153098106384 | 1.2123589515686 |
SwiftJSON | 不支持 | 不支持 |
MJExtension | 0.417935013771057 | 0.418874025344849 |
结果有点出乎意料,HandyJSON 的黑魔法纵然很强大,这也导致了耗时的问题,相比较而言,不太友好的 MJExtension 速度最快。
总结
对于应用开发来说,JSON 数据序列化和反序列号的操作必不可少,上述分析的效率和性能问题,也应该多考虑,选择合适的框架很重要,学习和踩坑也是并存的。
另外,Swift 支持 Codable 协议,对这个需求的处理也有很大的支持!