Swift:分別使用SwiftyJSON、ObjectMapper茁计、HandyJSON處理JSON

處理JSON數(shù)據(jù)是在開發(fā)過程中一定會遇到的一項操作料皇,通常情況下我們會先把JSON轉(zhuǎn)為Dictionary,記住每個數(shù)據(jù)對應(yīng)的Key星压,然后根據(jù)這個Key在Dictionary中取出對應(yīng)的Value值來践剂,那么除了在遇到一些比較復(fù)雜的JSON數(shù)據(jù)時候會顯得有些頭疼和繁瑣之外,可能還會經(jīng)常出現(xiàn)以下各種錯誤:

因此娜膘,為了解決這些問題逊脯,很多處理JSON的開源庫應(yīng)運而生。在Swift中竣贪,這些開源庫主要朝著兩個方向努力:

1.?保持JSON語義军洼,直接解析JSON,但通過封裝使調(diào)用方式更優(yōu)雅演怎、更安全匕争;

2.?預(yù)定義Model類,將JSON反序列化為類實例爷耀,再使用這些實例甘桑;

針對以上兩個方向,比較出名的有SwiftyJSONObjectMapper跑杭、HandyJSON铆帽, 下面就根據(jù)我個人的開發(fā)經(jīng)驗來分享一下各個框架在處理JSON過程中的使用委刘。

1氮采、SwiftyJSON

? SwiftyJSON的使用相對來說是最廣的, 它是針對上面提到的兩個方向中的第一條產(chǎn)生的一個庫纵搁,本質(zhì)上仍然是根據(jù)JSON結(jié)構(gòu)去取值窄做,使用起來比較順手愧驱、清晰。

?通常我們拿到數(shù)據(jù)會進行非常麻煩的Optinonal(可選類型)進行拆包(Wrapping )操作浸策,SwiftyJSON內(nèi)部會自動對Optinonal進行拆包冯键,大大簡化了代碼,解析非常方便庸汗,拿到的Json數(shù)據(jù)data直接扔進去惫确,例如:

我們不需要考慮服務(wù)器返回的是什么類型,比如去請求一個學(xué)生的age蚯舱, 我們想要獲得Int類型或者String類型都可以

通過 .stringValue改化、 .intValue?就可以獲得不可選值類型,如果沒有獲取到數(shù)據(jù)的話就會返回一個默認值即 .stringValue獲得空字符串""枉昏,.intValue得到 0陈肛,.arrayValue獲得空數(shù)組[],我們就不用判斷拆包了兄裂。除某些特定需要判斷類型的場景除外句旱。

如果我們擁有的是一個JSO格式的字符串,那么:

實際開發(fā)中晰奖,我們僅僅是對返回的數(shù)據(jù)進行JSON讀取是不夠的谈撒,如果遇到許多地方都用到了 name 值,但是當服務(wù)器給我們返回的字段名字改了匾南,我們改項目時就會顯得麻煩啃匿,甚至造成修改不完全,所以我們對數(shù)據(jù)封裝一下轉(zhuǎn)為模型蛆楞,這樣修改時只用修改model的一個屬性就可以了 ,? 例如:

創(chuàng)建模型溯乒,使用Class也可以,但是如果不需要繼承或者不是很復(fù)雜豹爹,推薦使用結(jié)構(gòu)體struct (可以參考 Swift — struct與class的差異

下面是如何將JSON轉(zhuǎn)成模型Model?

復(fù)雜模型裆悄,例如:?

這時候我們就要創(chuàng)建嵌套模型:

這樣就能很方便的取出?scores 里面的值?

以上就是針對?SwiftyJSON 的一些JSON處理

2 、ObjectMapper?

?ObjectMapper不同于SwiftyJSON的是把JSON映射成對象臂聋,為了支持映射灯帮,ObjectMapper中定義了一個協(xié)議崖技,類 class 或者結(jié)構(gòu)體 struct 需要實現(xiàn)Mappable協(xié)議, 這個協(xié)議包含下面兩個方法:

ObjectMapper使用自定義的 <- 運算符來聲明成員變量和JSON的映射關(guān)系钟哥,例如:

對象實現(xiàn)了 Mappable、ObjectMapper 就可以輕松的實現(xiàn)JSON 之間的轉(zhuǎn)換

或者:

或者復(fù)雜的數(shù)據(jù)結(jié)構(gòu):

ObjectMapper還有很多高級用法瞎访,如將model轉(zhuǎn)換為JSON腻贰, 自定義轉(zhuǎn)換規(guī)則等,詳細信息可參考?https://github.com/tristanhimmelman/ObjectMapper扒秸、https://www.hangge.com/blog/cache/detail_1675.html

3播演、HandyJSON

在使用了SwiftyJSONObjectMapper后會發(fā)現(xiàn),這兩種方法都還是有些缺陷的伴奥,首先我們要在model中指明每個屬性對應(yīng)的字段名写烤,不僅代碼侵入量大,而且拼寫錯誤拾徙,后期維護困難洲炊,而且Mapping函數(shù)要求開發(fā)者自定義?

HandyJSON 采用Swift反射+內(nèi)存賦值的方式來構(gòu)造Model實例,規(guī)避了上述兩個方案遇到的問題尼啡,不過HandyJSON也并非完美無缺暂衡,如經(jīng)常造成的內(nèi)存泄露,兼容性差等問題崖瞭,所以建議使用最新的HandyJSON庫

Model類想支持通過HandyJSON來反序列化狂巢,只需要在定義時,實現(xiàn)HandyJSON協(xié)議书聚,這個協(xié)議只要求實現(xiàn)一個空的init()函數(shù)?

下面就是一個舉例:

假如我們拿到這樣的一個JSON數(shù)據(jù)唧领,要怎樣來做反序列化呢?

這樣只需調(diào)用它的反序列函數(shù)就可以了,我們不用再一一指明model屬性對應(yīng)的字段名稱雌续,也不用擔心定義錯了數(shù)據(jù)類型斩个。 這是一個比較簡單的JSON轉(zhuǎn)model, 我們經(jīng)常會遇到些復(fù)雜的JSON數(shù)據(jù)

開發(fā)當中我們還會遇到些嵌套類型的model西雀, 如果model中的某一個屬性是另外一個自定義model萨驶,那么只要那個model類也實現(xiàn)了HandyJSON協(xié)議,就一樣可以轉(zhuǎn)換:

有時候服務(wù)端返回給我們很多和model無關(guān)信息艇肴,如 statusCode??腔呜, debugMessage等,或者有用的數(shù)據(jù)是在某個節(jié)點以下再悼,那么我們可以指定反序列化哪個節(jié)點:

如果某個model類繼承自另一個model類核畴,那么只需要這個父model類實現(xiàn) HandyJSON 協(xié)議就可以

此時我們要注意不能再使用struct,而要使用class創(chuàng)建model

HandyJSON還提供了一個擴展能力冲九,允許自行定義model類某個字段的解析Key谤草、解析方式跟束。

某個Model中,我們不想使用和服務(wù)端約定的Key作為屬性名丑孩,想自己定一個

有些類型如enum冀宴、tuple是無法直接從JSON中解析出來的,但我們在Model類中有這樣的屬性

HandyJSON協(xié)議提供了一個可選的mapping()函數(shù)温学,我們可以在其中指定某個字段用什么Key略贮、或者用什么方法從JSON中解析出它的值。如我們有一個model類和一個服務(wù)端返回的JSON數(shù)據(jù):

我們可以看到仗岖,User 的 id 屬性和 json 的Key是對應(yīng)不上的逃延, 而對于grandpas這個屬性來說,它是一個數(shù)組轧拄,做不到從json中的 "哈哈, 嘻嘻" 解析出來揽祥。所以我們要定義一個Mapping函數(shù)來做這兩個支持:

這樣就實現(xiàn)了HandyJSON的自定義解析方式

HandyJSON還支持枚舉屬性,實現(xiàn)支持枚舉檩电,enum 需要實現(xiàn) HandyJSONEnum 協(xié)議

當然拄丰,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

使用這些庫前要先分別導(dǎo)入SwiftyJSON愈案,ObjectMapper,?HandyJSON 如果需要導(dǎo)入的文件很多鹅搪,那么我們可以挑選一個自己喜歡的文件?@_exported import SwiftyJSON站绪,?@_exported import ObjectMapper,@_exported import HandyJSON 丽柿, 如此只需要導(dǎo)入一次就可以了

關(guān)于JSON轉(zhuǎn)Model的方法就說這么多了恢准,如有什么錯誤希望大家可以指出,有更多的方法也可以補充 甫题。 謝謝馁筐!




最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市坠非,隨后出現(xiàn)的幾起案子敏沉,更是在濱河造成了極大的恐慌,老刑警劉巖炎码,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盟迟,死亡現(xiàn)場離奇詭異,居然都是意外死亡潦闲,警方通過查閱死者的電腦和手機攒菠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來歉闰,“玉大人辖众,你說我怎么就攤上這事卓起。” “怎么了凹炸?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵戏阅,是天一觀的道長。 經(jīng)常有香客問我啤它,道長饲握,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任蚕键,我火速辦了婚禮,結(jié)果婚禮上衰粹,老公的妹妹穿的比我還像新娘锣光。我一直安慰自己,他們只是感情好铝耻,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布誊爹。 她就那樣靜靜地躺著,像睡著了一般瓢捉。 火紅的嫁衣襯著肌膚如雪频丘。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天泡态,我揣著相機與錄音搂漠,去河邊找鬼。 笑死某弦,一個胖子當著我的面吹牛桐汤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播靶壮,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼怔毛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了腾降?” 一聲冷哼從身側(cè)響起拣度,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎螃壤,沒想到半個月后抗果,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡映穗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年窖张,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚁滋。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡宿接,死狀恐怖赘淮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情睦霎,我是刑警寧澤梢卸,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站副女,受9級特大地震影響蛤高,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜碑幅,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一戴陡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧沟涨,春花似錦恤批、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至棋返,卻和暖如春延都,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背睛竣。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工晰房, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人酵颁。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓嫉你,卻偏偏與公主長得像,于是被迫代替她去往敵國和親躏惋。 傳聞我的和親對象是個殘疾皇子幽污,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容