(这是该问题的后续内容: 使用具有多个键的可解码协议。)
我有以下Swift代码:
let additionalInfo = try values.nestedContainer(keyedBy: UserInfoKeys.self, forKey: .age) age = try additionalInfo.decodeIfPresent(Int.self, forKey: .realage)
我知道,如果我使用decodeIfPresent并且没有该属性,但如果它是一个可选变量,它仍然可以正确处理它。
decodeIfPresent
例如,以下JSON可使用上面的代码来解析它。
{ "firstname": "Test", "lastname": "User", "age": {"realage": 29} }
以下JSON也适用。
{ "firstname": "Test", "lastname": "User", "age": {"notrealage": 30} }
但是以下操作无效。
{ "firstname": "Test", "lastname": "User" }
如何使所有3个示例正常工作?有什么类似decodeIfPresent的nestedContainer?
nestedContainer
您可以使用以下KeyedDecodingContainer功能:
KeyedDecodingContainer
func contains(_ key: KeyedDecodingContainer.Key) -> Bool
返回一个Bool值,该值指示解码器是否包含与给定密钥关联的值。与给定键关联的值可以是适合于数据格式的空值。
Bool
例如, 在 请求相应的嵌套容器 之前 要检查"age"键是否存在: __
"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 } } }