Swift可解码的可选键

(这是这个问题的一个后续: 使用具有多个键的可解码协议 。)

我有以下的Swift代码:

let additionalInfo = try values.nestedContainer(keyedBy: UserInfoKeys.self, forKey: .age) age = try additionalInfo.decodeIfPresent(Int.self, forKey: .realage) 

我知道,如果我使用decodeIfPresent并没有该属性,它仍然会正确处理它,如果它是一个可选的variables。

例如,下面的JSON使用上面的代码来parsing它。

 { "firstname": "Test", "lastname": "User", "age": {"realage": 29} } 

而下面的JSON也适用。

 { "firstname": "Test", "lastname": "User", "age": {"notrealage": 30} } 

但以下不起作用。

 { "firstname": "Test", "lastname": "User" } 

我怎样才能使所有3个例子工作? 对于nestedContainer有没有类似nestedContainer

您可以使用以下KeyedDecodingContainer函数:

 func contains(_ key: KeyedDecodingContainer.Key) -> Bool 

返回一个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 } } } 

你可以尝试将你的示例JSON粘贴到快速types,看看它推断的types? 根据你的问题,我粘贴你的样品,得到:

 struct UserInfo: Codable { let firstname: String let age: Age? let lastname: String } struct Age: Codable { let realage: Int? } 

使UserInfo.ageAge.realage选项有效,如果这就是你想要完成的。