實測 JSON Decode:Codable Protocol 真的這麼好用嗎?


本篇原文(標題:真實世界的 JSON Decode)刊登於作者 Medium,由 David Lin 所著並授權轉載。

雖然這次 Apple 幫我們做出了 Codable 這個好用的 protocol,但上了戰場之後呢?

如果你已經試過 Swift 4 提供的 Codable protocol,你應該發現 json decode 在 Swift 中已經不像以前那麼不方便了,也不需要再經過 dictionary 的轉換拖慢 decode 速度(像是第三方解析 json 套件:SwiftyJSON)。但 Codable 真的這麼好用嗎?不知道你有沒有注意到,有時候 backend 會因為使用套件的關係,回傳的 json 中會有 {} (空的 json)或者 “”(空字串),這樣會造成 json decode 失敗。

本文專注於在不自己實作 Decodable protocol 中 init(from decoder: Decoder) throws 方法,如果習慣自己實作此 init method 的朋友,將可能不會遇到此問題。

本篇文章將會專注於處理特殊 json 回傳情況,不熟悉 Codable 的朋友,可以參考這篇文章。

情況一:空的 json { }

假設我們有一個 json data 如下,title 是字串,其他兩個 cover 是 BookCover 類別,我們要從 json data 轉換成可以使用的物件,但可以看到 frontCover 回傳的是一個空的 json,這將造成物件轉換失敗。

失敗的訊息如下:

keyNotFound(lldbexpr148.BookCover.CodingKeys.text, Swift.DecodingError.Context(codingPath: [lldbexpr148.Book.(CodingKeys in 26B35E459B7D5969E8B4869C3A09F28B).frontCover], debugDescription: “No value associated with key text (\”text\”).”, underlyingError: nil))

原因是當我們在轉換 frontCover 時,找不到 title 這個 key 所致。當然,在一個空的 json 中,一定找不到任何 key。

解決方式

因為 frontCover 的型態是 optional 的 BookCover,所以在 decode 時,將會執行 decodeIfPresent 來檢查是否為 nil,現在我們要來對有這個 function 的 KeyedDecodingContainer 做一些 extension。

首先要先建立一個 protocol 來處理回傳空 json 的情況,並且對 KeyedDecodingContainer 做一些 extension。

最後回到類別,並且讓他 conform protocol 即可。

情況二:空的字串

類似於上面的狀況,只是空的 json {} 變成空的字串 “”,這個情況下因為 Genre 是 String 資料型態的 enum,所以我們預設有一個 init?(rawValue: String) 的 init method,但如果我們傳入空的字串到 init method 中,就會失敗(回傳 nil)。

結語

以前自己在接 rails 丟的 api 時常常會看到這類情況發生,而當初使用 swiftyJSON 因為只要給一個字串做 subscript 即可拿到想要的值,方便好用且無腦。

但 Codable 這個 protocol 雖然讓解析 json 變得不需要再使用第三方套件,速度應該比轉成 dictionary 更快(沒經過驗證),但也可以看到他對於 json 中的 {}, null, “” 處理上變得更麻煩,如果沒有先確定 backend 回傳型態,一個不小心可能會整個炸掉。

其實這翻譯文章寫到一半我已經心很累,原本想說 Codable 會讓程式變得更乾淨,但現在看起來維護性上其實變得頗差,容錯率也變低,寫起來更麻煩。我想我應該會回去使用慢到炸的 SwiftyJSON 吧?

如果有更好的解法,歡迎留言討論喔!

本篇原文(標題:真實世界的 JSON Decode)刊登於作者 Medium,由 David Lin 所著並授權轉載。
作者簡介:David Lin,前 Colorgy iOS 工程師,目前為自由工作者,平時接接案、寫寫文章。為 Swift 愛好者,從 Swift 1.2 就入火坑到現在。目前專注於研究 mobile 架構,從 MVC, MVVM, VIPER, Clean architecture, complex deep link routing 都有研究,想找出適用於 mobile development 皆適用的架構。興趣為:爬山、攝影。曾在 Hahow 上有一線上課程:iOS 入門-從介面設計到開發。Facebook: fb.com/yoxisem544

此文章為客座或轉載文章,由作者授權刊登,AppCoda編輯團隊編輯。有關文章詳情,請參考文首或文末的簡介。

blog comments powered by Disqus
訂閲電子報

訂閲電子報

AppCoda致力於發佈優質iOS程式教學,你不必每天上站,輸入你的電子郵件地址訂閱網站的最新教學文章。每當有新文章發佈,我們會使用電子郵件通知你。

已收你的指示。請你檢查你的電郵,我們已寄出一封認證信,點擊信中鏈結才算完成訂閱。

Shares
Share This