[Swift]Swift原生:JSON轉換Model


★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公眾號:山青詠芝(let_us_code)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: https:////www.cnblogs.com/strengthen/p/12381682.html
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持作者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

熱烈歡迎,請直接點擊!!!

進入博主App Store主頁,下載使用各個作品!!!

注:博主將堅持每月上線一個新app!!!

Apple 在 Swift  的 Foundation 的模塊中添加了對 JSON 解析成Model的原生支持。

雖然之前也有ObjectMapperSwiftyJSON這樣的解決方案,但是Swift 中添加了原生支持還是不免讓人興奮,使用起來也相對方便了許多。

簡單使用

如果你的 JSON 數據結構和你使用的 Model 對象結構一致的話,那么解析過程將會非常簡單。只需要讓Model聲明 Codable 協議即可。

JSON數據:

 1 {
 2     "userInfos": [
 3         {
 4             "userName": "小名",
 5             "age": 18,
 6             "height": 178.56,
 7             "sex": true
 8         },
 9         {
10             "userName": "小方",
11             "age": 18,
12             "height": 162.56,
13             "sex": false
14         }
15     ]
16 }

Model對象:

 1 struct UserList: Codable {
 2 
 3     let userInfos: [UserInfo]
 4 
 5     struct UserInfo: Codable {
 6 
 7         let userName: String
 8         let age: Int
 9         let height: Float
10         let sex: Bool
11     }
12 }

JSON轉Model:

1     let jsonDecoder = JSONDecoder()
2     let modelObject = try? jsonDecoder.decode(UserList.self, from: jsonData)

Model轉JSON:

1     let jsonEncoder = JSONEncoder()
2     let jsonData = try? jsonEncoder.encode(modelObject)

關於 Codable

1 /// A type that can convert itself into and out of an external representation.
2 public typealias Codable = Decodable & Encodable

Codable 同時聲明了 Decodable 和 Encodable 兩個協議,只需要單向處理的話可以只聲明其中一個協議。

需要注意的是,使用時必須保證 JSON 數據結構和你使用的 Model 對象結構一致,任何不一致都會導致解析失敗。

但是實際開發過程中,往往不會總是這樣滿足我們的需要,有時也需要我們對解析過程做一些改變。

自定義鍵值名

為了保持風格一致,我們有時候不得不改變key成為我們需要的key值。

仍然使用上面的例子,現在我們把Model中的key height 改為 bodyHeight

 1 struct UserList: Codable {
 2 
 3     let userInfos: [UserInfo]
 4     
 5     struct UserInfo: Codable {
 6         
 7         let userName: String
 8         let age: Int
 9         let bodyHeight: Float
10         let sex: Bool
11         
12         private enum CodingKeys: String, CodingKey {
13             case userName
14             case age
15             case bodyHeight = "height"
16             case sex
17         }
18     }
19 }

格式處理

JSONEncoder 和 JSONDecoder 本身也提供了對時間格式的處理,Data的處理,浮點不匹配的處理。可以根據自己的需要設置自己想要的格式。

1     /// The strategy to use in decoding dates. Defaults to `.deferredToDate`.
2     open var dateDecodingStrategy: JSONDecoder.DateDecodingStrategy
3 
4     /// The strategy to use in decoding binary data. Defaults to `.base64`.
5     open var dataDecodingStrategy: JSONDecoder.DataDecodingStrategy
6 
7     /// The strategy to use in decoding non-conforming numbers. Defaults to `.throw`.
8     open var nonConformingFloatDecodingStrategy: JSONDecoder.NonConformingFloatDecodingStrategy

JSONEncoder 在生成 JSON 的時候默認的格式是

{"userInfos":[{"age":18,"sex":true,"height":178.55999755859375,"userName":"小名"},{"age":18,"sex":false,"height":162.55999755859375,"userName":"小方"}]}

如果想要提高閱讀體驗, 可以設置屬性 outputFormatting

1 open var outputFormatting: JSONEncoder.OutputFormatting
2 
3 let jsonEncoder = JSONEncoder()
4 jsonEncoder.outputFormatting = .prettyPrinted

然后生成的JSON格式就會變成這樣

 1 {
 2   "userInfos" : [
 3     {
 4       "age" : 18,
 5       "sex" : true,
 6       "height" : 178.55999755859375,
 7       "userName" : "小名"
 8     },
 9     {
10       "age" : 18,
11       "sex" : false,
12       "height" : 162.55999755859375,
13       "userName" : "小方"
14     }
15   ]
16 }

JSON中 沒有 Model 所需要的 Key

如果JSON的數據結構中,有些 Key - Value 不一定出現,Model中對應的要實用可選類型

JSON數據:

 1 {
 2     "userInfos": [
 3         {
 4             "userName": "小名",
 5             "age": 18,
 6             "sex": true
 7         },
 8         {
 9             "userName": "小方",
10             "age": 18,
11             "height": 162.56,
12             "sex": false
13         }
14     ]
15 }

Model對象:

 1 struct UserList: Codable {
 2 
 3     let userInfos: [UserInfo]
 4 
 5     struct UserInfo: Codable {
 6 
 7         let userName: String
 8         let age: Int
 9         let height: Float?
10         let sex: Bool
11     }
12 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM