★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公眾號:山青詠芝(let_us_code)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: https:////www.cnblogs.com/strengthen/p/12381682.html
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持作者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
Apple 在 Swift 的 Foundation 的模塊中添加了對 JSON 解析成Model的原生支持。
雖然之前也有ObjectMapper和SwiftyJSON這樣的解決方案,但是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 }