Cha*_*ish 1 json swift swift4 codable
假设我有以下代码:
import Foundation
let jsonData = """
[
{"firstname": "Tom", "lastname": "Smith", "age": {"realage": "28"}},
{"firstname": "Bob", "lastname": "Smith", "age": {"fakeage": "31"}}
]
""".data(using: .utf8)!
struct Person: Codable {
let firstName, lastName: String
let age: String?
enum CodingKeys : String, CodingKey {
case firstName = "firstname"
case lastName = "lastname"
case age
}
}
let decoded = try JSONDecoder().decode([Person].self, from: jsonData)
print(decoded)
Run Code Online (Sandbox Code Playgroud)
一切都在工作,除了age
总是nil
。这是有道理的。我的问题是如何在第一个示例和第二个示例中设置人的年龄 =realage
或。取而代之的是在这两种情况下,我想这是在第一种情况。28
nil
age
nil
28
有没有办法只使用CodingKeys
而不必添加另一个结构或类来实现这一点?如果不是,我如何使用另一个结构或类以最简单的方式实现我想要的?
在解码嵌套 JSON 数据时,我最喜欢的方法是定义一个与 JSON 非常接近的“原始”模型,即使snake_case
需要也可以使用。它有助于将 JSON 数据快速导入 Swift,然后您可以使用 Swift 进行您需要的操作:
struct Person: Decodable {
let firstName, lastName: String
let age: String?
// This matches the keys in the JSON so we don't have to write custom CodingKeys
private struct RawPerson: Decodable {
struct RawAge: Decodable {
let realage: String?
let fakeage: String?
}
let firstname: String
let lastname: String
let age: RawAge
}
init(from decoder: Decoder) throws {
let rawPerson = try RawPerson(from: decoder)
self.firstName = rawPerson.firstname
self.lastName = rawPerson.lastname
self.age = rawPerson.age.realage
}
}
Run Code Online (Sandbox Code Playgroud)
另外,我建议您谨慎使用Codable
,因为它同时包含Encodable
和Decodable
。似乎您只需Decodable
要使您的模型符合该协议即可。
归档时间: |
|
查看次数: |
1992 次 |
最近记录: |