快速可解码可选键 [英] Swift Decodable Optional Key

查看:83
本文介绍了快速可解码可选键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(这是该问题的后续内容:使用具有多个键的可解码协议.)

我有以下Swift代码:

I have the following Swift code:

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

我知道,如果我使用decodeIfPresent并且没有该属性,并且它是一个可选变量,它仍然可以正确处理它.

I know that if I use decodeIfPresent and don't have the property it will still handle it correctly if it's an optional variable.

例如,以下JSON可以使用上面的代码来解析它.

For example the following JSON works to parse it using the code above.

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

以下JSON也可以使用.

And the following JSON works as well.

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

但是以下方法不起作用.

But the following doesn't work.

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

如何使所有3个示例正常工作? nestedContainer是否有与decodeIfPresent类似的东西?

How can I make all 3 examples work? Is there something similar to decodeIfPresent for nestedContainer?

推荐答案

您可以使用以下

You can use the following KeyedDecodingContainer function:

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

返回一个Bool值,该值指示解码器是否包含与给定密钥关联的值.与给定键相关联的值可以为空值,以适合数据格式.

Returns a Bool value indicating whether the decoder contains a value associated with the given key. The value associated with the given key may be a null value as appropriate for the data format.

例如,要在请求相应的嵌套容器之前,在 之前检查"age"键是否存在:

For instance, to check if the "age" key exists before requesting the corresponding nested container:

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
        }
    }
}

这篇关于快速可解码可选键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆