将可解码协议与多个键一起使用 [英] Using Decodable protocol with multiples keys

查看:76
本文介绍了将可解码协议与多个键一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有以下代码:

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)

age 始终为 nil 之外,其他所有内容均正常。有道理。我的问题是如何在第一个示例中设置人员的年龄= 实际年龄 28 c> nil 在第二个示例中。在这两种情况下,我都不希望 age nil ,而我希望它是 28 在第一种情况下。

Everything is working except age is always nil. Which makes sense. My question is how can I set the Person's age = realage or 28 in the first example, and nil in the second example. Instead of age being nil in both cases I want it to be 28 in the first case.

有没有一种方法可以仅使用 CodingKeys 来实现此目的添加另一个结构或类?如果不能,我该如何使用另一个结构或类以最简单的方式实现我想要的?

Is there a way to achieve this only using CodingKeys and not having to add another struct or class? If not how can I use another struct or class to achieve what I want in the simplest way possible?

推荐答案

我最喜欢的方法是关于解码嵌套的JSON数据,是定义一个非常接近JSON的原始模型,甚至在需要时甚至使用 snake_case 。它有助于将JSON数据真正快速地带入Swift,然后您可以使用Swift进行所需的操作:

My favorite approach when it comes to decoding nested JSON data is to define a "raw" model that stays very close to the JSON, even using snake_case if needed. It help bringing JSON data into Swift really quickly, then you can use Swift to do the manipulations you need:

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

此外,我建议您成为明智地使用 Codable ,因为它暗示了 Encodable Decodable 。看来您只需要可解码的,因此仅使模型符合该协议即可。

Also, I recommend you to be judicious with the use of Codable, as it implies both Encodable and Decodable. It seems like you only need Decodable so conform your model to that protocol only.

这篇关于将可解码协议与多个键一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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