javascript
Swift:分别使用SwiftyJSON、ObjectMapper、HandyJSON处理JSON
https://www.jianshu.com/p/eeb6c673aeb4
2018.12.21 00:43:33字?jǐn)?shù) 1,947閱讀 2,612
https://www.cnblogs.com/xjf125/p/10704369.html
處理JSON數(shù)據(jù)是在開發(fā)過程中一定會(huì)遇到的一項(xiàng)操作,通常情況下我們會(huì)先把JSON轉(zhuǎn)為Dictionary,記住每個(gè)數(shù)據(jù)對(duì)應(yīng)的Key,然后根據(jù)這個(gè)Key在Dictionary中取出對(duì)應(yīng)的Value值來,那么除了在遇到一些比較復(fù)雜的JSON數(shù)據(jù)時(shí)候會(huì)顯得有些頭疼和繁瑣之外,可能還會(huì)經(jīng)常出現(xiàn)以下各種錯(cuò)誤:
因此,為了解決這些問題,很多處理JSON的開源庫應(yīng)運(yùn)而生。在Swift中,這些開源庫主要朝著兩個(gè)方向努力:
1.?保持JSON語義,直接解析JSON,但通過封裝使調(diào)用方式更優(yōu)雅、更安全;
2.?預(yù)定義Model類,將JSON反序列化為類實(shí)例,再使用這些實(shí)例;
針對(duì)以上兩個(gè)方向,比較出名的有SwiftyJSON、ObjectMapper、HandyJSON,?下面就根據(jù)我個(gè)人的開發(fā)經(jīng)驗(yàn)來分享一下各個(gè)框架在處理JSON過程中的使用。
1、SwiftyJSON
? SwiftyJSON的使用相對(duì)來說是最廣的, 它是針對(duì)上面提到的兩個(gè)方向中的第一條產(chǎn)生的一個(gè)庫,本質(zhì)上仍然是根據(jù)JSON結(jié)構(gòu)去取值,使用起來比較順手、清晰。
?通常我們拿到數(shù)據(jù)會(huì)進(jìn)行非常麻煩的Optinonal(可選類型)進(jìn)行拆包(Wrapping )操作,SwiftyJSON內(nèi)部會(huì)自動(dòng)對(duì)Optinonal進(jìn)行拆包,大大簡化了代碼,解析非常方便,拿到的Json數(shù)據(jù)data直接扔進(jìn)去,例如:
我們不需要考慮服務(wù)器返回的是什么類型,比如去請(qǐng)求一個(gè)學(xué)生的age, 我們想要獲得Int類型或者String類型都可以
通過 .stringValue、 .intValue?就可以獲得不可選值類型,如果沒有獲取到數(shù)據(jù)的話就會(huì)返回一個(gè)默認(rèn)值即 .stringValue獲得空字符串"",.intValue得到 0,.arrayValue獲得空數(shù)組[],我們就不用判斷拆包了。除某些特定需要判斷類型的場景除外。
如果我們擁有的是一個(gè)JSO格式的字符串,那么:
實(shí)際開發(fā)中,我們僅僅是對(duì)返回的數(shù)據(jù)進(jìn)行JSON讀取是不夠的,如果遇到許多地方都用到了 name 值,但是當(dāng)服務(wù)器給我們返回的字段名字改了,我們改項(xiàng)目時(shí)就會(huì)顯得麻煩,甚至造成修改不完全,所以我們對(duì)數(shù)據(jù)封裝一下轉(zhuǎn)為模型,這樣修改時(shí)只用修改model的一個(gè)屬性就可以了 ,? 例如:
創(chuàng)建模型,使用Class也可以,但是如果不需要繼承或者不是很復(fù)雜,推薦使用結(jié)構(gòu)體struct (可以參考?Swift — struct與class的差異)
下面是如何將JSON轉(zhuǎn)成模型Model?
復(fù)雜模型,例如:?
這時(shí)候我們就要?jiǎng)?chuàng)建嵌套模型:
這樣就能很方便的取出?scores 里面的值?
以上就是針對(duì)?SwiftyJSON?的一些JSON處理
2 、ObjectMapper?
?ObjectMapper不同于SwiftyJSON的是把JSON映射成對(duì)象,為了支持映射,ObjectMapper中定義了一個(gè)協(xié)議,類 class 或者結(jié)構(gòu)體 struct 需要實(shí)現(xiàn)Mappable協(xié)議, 這個(gè)協(xié)議包含下面兩個(gè)方法:
ObjectMapper使用自定義的 <- 運(yùn)算符來聲明成員變量和JSON的映射關(guān)系,例如:
對(duì)象實(shí)現(xiàn)了 Mappable、ObjectMapper 就可以輕松的實(shí)現(xiàn)JSON 之間的轉(zhuǎn)換
或者:
或者復(fù)雜的數(shù)據(jù)結(jié)構(gòu):
ObjectMapper還有很多高級(jí)用法,如將model轉(zhuǎn)換為JSON, 自定義轉(zhuǎn)換規(guī)則等,詳細(xì)信息可參考?https://github.com/tristanhimmelman/ObjectMapper、https://www.hangge.com/blog/cache/detail_1675.html
3、HandyJSON
在使用了SwiftyJSON和ObjectMapper后會(huì)發(fā)現(xiàn),這兩種方法都還是有些缺陷的,首先我們要在model中指明每個(gè)屬性對(duì)應(yīng)的字段名,不僅代碼侵入量大,而且拼寫錯(cuò)誤,后期維護(hù)困難,而且Mapping函數(shù)要求開發(fā)者自定義?
HandyJSON 采用Swift反射+內(nèi)存賦值的方式來構(gòu)造Model實(shí)例,規(guī)避了上述兩個(gè)方案遇到的問題,不過HandyJSON也并非完美無缺,如經(jīng)常造成的內(nèi)存泄露,兼容性差等問題,所以建議使用最新的HandyJSON庫
Model類想支持通過HandyJSON來反序列化,只需要在定義時(shí),實(shí)現(xiàn)HandyJSON協(xié)議,這個(gè)協(xié)議只要求實(shí)現(xiàn)一個(gè)空的init()函數(shù)?
下面就是一個(gè)舉例:
假如我們拿到這樣的一個(gè)JSON數(shù)據(jù),要怎樣來做反序列化呢?
這樣只需調(diào)用它的反序列函數(shù)就可以了,我們不用再一一指明model屬性對(duì)應(yīng)的字段名稱,也不用擔(dān)心定義錯(cuò)了數(shù)據(jù)類型。 這是一個(gè)比較簡單的JSON轉(zhuǎn)model, 我們經(jīng)常會(huì)遇到些復(fù)雜的JSON數(shù)據(jù)
開發(fā)當(dāng)中我們還會(huì)遇到些嵌套類型的model, 如果model中的某一個(gè)屬性是另外一個(gè)自定義model,那么只要那個(gè)model類也實(shí)現(xiàn)了HandyJSON協(xié)議,就一樣可以轉(zhuǎn)換:
有時(shí)候服務(wù)端返回給我們很多和model無關(guān)信息,如 statusCode??, debugMessage等,或者有用的數(shù)據(jù)是在某個(gè)節(jié)點(diǎn)以下,那么我們可以指定反序列化哪個(gè)節(jié)點(diǎn):
如果某個(gè)model類繼承自另一個(gè)model類,那么只需要這個(gè)父model類實(shí)現(xiàn) HandyJSON 協(xié)議就可以
此時(shí)我們要注意不能再使用struct,而要使用class創(chuàng)建model
HandyJSON還提供了一個(gè)擴(kuò)展能力,允許自行定義model類某個(gè)字段的解析Key、解析方式。
某個(gè)Model中,我們不想使用和服務(wù)端約定的Key作為屬性名,想自己定一個(gè)
有些類型如enum、tuple是無法直接從JSON中解析出來的,但我們?cè)贛odel類中有這樣的屬性
HandyJSON協(xié)議提供了一個(gè)可選的mapping()函數(shù),我們可以在其中指定某個(gè)字段用什么Key、或者用什么方法從JSON中解析出它的值。如我們有一個(gè)model類和一個(gè)服務(wù)端返回的JSON數(shù)據(jù):
我們可以看到,User 的 id 屬性和 json 的Key是對(duì)應(yīng)不上的, 而對(duì)于grandpas這個(gè)屬性來說,它是一個(gè)數(shù)組,做不到從json中的 "哈哈, 嘻嘻" 解析出來。所以我們要定義一個(gè)Mapping函數(shù)來做這兩個(gè)支持:
這樣就實(shí)現(xiàn)了HandyJSON的自定義解析方式
HandyJSON還支持枚舉屬性,實(shí)現(xiàn)支持枚舉,enum 需要實(shí)現(xiàn) HandyJSONEnum 協(xié)議
當(dāng)然,HandyJSON 也提供了把Model類序列化為JSON文本的能力,這里就不做介紹了,詳細(xì)方法可以參考:?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
使用這些庫前要先分別導(dǎo)入SwiftyJSON,ObjectMapper,?HandyJSON 如果需要導(dǎo)入的文件很多,那么我們可以挑選一個(gè)自己喜歡的文件?@_exported import SwiftyJSON,?@_exported import ObjectMapper,@_exported import HandyJSON , 如此只需要導(dǎo)入一次就可以了
關(guān)于JSON轉(zhuǎn)Model的方法就說這么多了,如有什么錯(cuò)誤希望大家可以指出,有更多的方法也可以補(bǔ)充 。 謝謝!
總結(jié)
以上是生活随笔為你收集整理的Swift:分别使用SwiftyJSON、ObjectMapper、HandyJSON处理JSON的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PDK文件学习
- 下一篇: swift moya框架+rxswift