Swift:分别使用SwiftyJSON、ObjectMapper、HandyJSON处理JSON

处理JSON数据是在开发过程中一定会遇到的一项操作,通常情况下我们会先把JSON转为Dictionary,记住每个数据对应的Key,然后根据这个Key在Dictionary中取出对应的Value值来,那么除了在遇到一些比较复杂的JSON数据时候会显得有些头疼和繁琐之外,可能还会经常出现以下各种错误:

因此,为了解决这些问题,很多处理JSON的开源库应运而生。在Swift中,这些开源库主要朝着两个方向努力:

1. 保持JSON语义,直接解析JSON,但通过封装使调用方式更优雅、更安全;

2. 预定义Model类,将JSON反序列化为类实例,再使用这些实例;

针对以上两个方向,比较出名的有SwiftyJSONObjectMapperHandyJSON, 下面就根据我个人的开发经验来分享一下各个框架在处理JSON过程中的使用。

1、SwiftyJSON

  SwiftyJSON的使用相对来说是最广的, 它是针对上面提到的两个方向中的第一条产生的一个库,本质上仍然是根据JSON结构去取值,使用起来比较顺手、清晰。

 通常我们拿到数据会进行非常麻烦的Optinonal(可选类型)进行拆包(Wrapping )操作,SwiftyJSON内部会自动对Optinonal进行拆包,大大简化了代码,解析非常方便,拿到的Json数据data直接扔进去,例如:

我们不需要考虑服务器返回的是什么类型,比如去请求一个学生的age, 我们想要获得Int类型或者String类型都可以

通过 .stringValue、 .intValue 就可以获得不可选值类型,如果没有获取到数据的话就会返回一个默认值即 .stringValue获得空字符串"",.intValue得到 0,.arrayValue获得空数组[],我们就不用判断拆包了。除某些特定需要判断类型的场景除外。

如果我们拥有的是一个JSO格式的字符串,那么:

实际开发中,我们仅仅是对返回的数据进行JSON读取是不够的,如果遇到许多地方都用到了 name 值,但是当服务器给我们返回的字段名字改了,我们改项目时就会显得麻烦,甚至造成修改不完全,所以我们对数据封装一下转为模型,这样修改时只用修改model的一个属性就可以了 ,  例如:

创建模型,使用Class也可以,但是如果不需要继承或者不是很复杂,推荐使用结构体struct (可以参考 Swift — struct与class的差异

下面是如何将JSON转成模型Model 

复杂模型,例如: 

这时候我们就要创建嵌套模型:

这样就能很方便的取出 scores 里面的值 

以上就是针对 SwiftyJSON 的一些JSON处理

2 、ObjectMapper 

 ObjectMapper不同于SwiftyJSON的是把JSON映射成对象,为了支持映射,ObjectMapper中定义了一个协议,类 class 或者结构体 struct 需要实现Mappable协议, 这个协议包含下面两个方法:

ObjectMapper使用自定义的 <- 运算符来声明成员变量和JSON的映射关系,例如:

对象实现了 Mappable、ObjectMapper 就可以轻松的实现JSON 之间的转换

或者:

或者复杂的数据结构:

ObjectMapper还有很多高级用法,如将model转换为JSON, 自定义转换规则等,详细信息可参考 https://github.com/tristanhimmelman/ObjectMapperhttps://www.hangge.com/blog/cache/detail_1675.html

3、HandyJSON

在使用了SwiftyJSONObjectMapper后会发现,这两种方法都还是有些缺陷的,首先我们要在model中指明每个属性对应的字段名,不仅代码侵入量大,而且拼写错误,后期维护困难,而且Mapping函数要求开发者自定义 

HandyJSON 采用Swift反射+内存赋值的方式来构造Model实例,规避了上述两个方案遇到的问题,不过HandyJSON也并非完美无缺,如经常造成的内存泄露,兼容性差等问题,所以建议使用最新的HandyJSON库

Model类想支持通过HandyJSON来反序列化,只需要在定义时,实现HandyJSON协议,这个协议只要求实现一个空的init()函数 

下面就是一个举例:

假如我们拿到这样的一个JSON数据,要怎样来做反序列化呢 

这样只需调用它的反序列函数就可以了,我们不用再一一指明model属性对应的字段名称,也不用担心定义错了数据类型。 这是一个比较简单的JSON转model, 我们经常会遇到些复杂的JSON数据

开发当中我们还会遇到些嵌套类型的model, 如果model中的某一个属性是另外一个自定义model,那么只要那个model类也实现了HandyJSON协议,就一样可以转换:

有时候服务端返回给我们很多和model无关信息,如 statusCode  , debugMessage等,或者有用的数据是在某个节点以下,那么我们可以指定反序列化哪个节点:

如果某个model类继承自另一个model类,那么只需要这个父model类实现 HandyJSON 协议就可以

此时我们要注意不能再使用struct,而要使用class创建model

HandyJSON还提供了一个扩展能力,允许自行定义model类某个字段的解析Key、解析方式。

某个Model中,我们不想使用和服务端约定的Key作为属性名,想自己定一个

有些类型如enum、tuple是无法直接从JSON中解析出来的,但我们在Model类中有这样的属性

HandyJSON协议提供了一个可选的mapping()函数,我们可以在其中指定某个字段用什么Key、或者用什么方法从JSON中解析出它的值。如我们有一个model类和一个服务端返回的JSON数据:

我们可以看到,User 的 id 属性和 json 的Key是对应不上的, 而对于grandpas这个属性来说,它是一个数组,做不到从json中的 "哈哈, 嘻嘻" 解析出来。所以我们要定义一个Mapping函数来做这两个支持:

这样就实现了HandyJSON的自定义解析方式

HandyJSON还支持枚举属性,实现支持枚举,enum 需要实现 HandyJSONEnum 协议

当然,HandyJSON 也提供了把Model类序列化为JSON文本的能力,这里就不做介绍了,详细方法可以参考: https://github.com/alibaba/handyjson#the-basics    http://www.cnblogs.com/crazyacking/p/5927909.html?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#_label00

使用这些库前要先分别导入SwiftyJSON,ObjectMapper, HandyJSON 如果需要导入的文件很多,那么我们可以挑选一个自己喜欢的文件 @_exported import SwiftyJSON, @_exported import ObjectMapper,@_exported import HandyJSON , 如此只需要导入一次就可以了

关于JSON转Model的方法就说这么多了,如有什么错误希望大家可以指出,有更多的方法也可以补充 。 谢谢!




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

推荐阅读更多精彩内容