Cha*_*ish 13 json ios swift swift4 codable
(这是此问题的后续跟进:使用具有多个键的可解码协议.)
我有以下Swift代码:
let additionalInfo = try values.nestedContainer(keyedBy: UserInfoKeys.self, forKey: .age)
age = try additionalInfo.decodeIfPresent(Int.self, forKey: .realage)
Run Code Online (Sandbox Code Playgroud)
我知道如果我使用decodeIfPresent并且没有该属性,如果它是一个可选变量,它仍将正确处理它.
例如,以下JSON使用上面的代码解析它.
{
"firstname": "Test",
"lastname": "User",
"age": {"realage": 29}
}
Run Code Online (Sandbox Code Playgroud)
以下JSON也适用.
{
"firstname": "Test",
"lastname": "User",
"age": {"notrealage": 30}
}
Run Code Online (Sandbox Code Playgroud)
但以下不起作用.
{
"firstname": "Test",
"lastname": "User"
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能使所有3个例子都有效?是否有类似的东西decodeIfPresent了nestedContainer?
Pau*_*tos 43
您可以使用以下KeyedDecodingContainer功能:
func contains(_ key: KeyedDecodingContainer.Key) -> Bool
Run Code Online (Sandbox Code Playgroud)
返回一个
Bool值,指示解码器是否包含与给定键关联的值.与给定密钥相关联的值可以是适合于数据格式的空值.
例如,在请求相应的嵌套容器之前检查"age"密钥是否存在:
struct Person: Decodable {
let firstName, lastName: String
let age: Int?
enum CodingKeys: String, CodingKey {
case firstName = "firstname"
case lastName = "lastname"
case age
}
enum AgeKeys: String, CodingKey {
case realAge = "realage"
case fakeAge = "fakeage"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
self.firstName = try values.decode(String.self, forKey: .firstName)
self.lastName = try values.decode(String.self, forKey: .lastName)
if values.contains(.age) {
let age = try values.nestedContainer(keyedBy: AgeKeys.self, forKey: .age)
self.age = try age.decodeIfPresent(Int.self, forKey: .realAge)
} else {
self.age = nil
}
}
}
Run Code Online (Sandbox Code Playgroud)
我遇到了这个问题,我找到了这个解决方案,以防万一对其他人有帮助:
let ageContainer = try? values.nestedContainer(keyedBy: AgeKeys.self, forKey: .age)
self.age = try ageContainer?.decodeIfPresent(Int.self, forKey: .realAge)
Run Code Online (Sandbox Code Playgroud)
如果你有一个可选的容器, usingtry? values.nestedContainer(keyedBy:forKey)你不需要使用contains(.
| 归档时间: |
|
| 查看次数: |
9811 次 |
| 最近记录: |