Swift Codable 手动解码可选变量

Swift Codable Decode Manually Optional Variable

我有以下代码:

import Foundation

let jsonData = """
[
    {"firstname": "Tom", "lastname": "Smith", "age": "28"},
    {"firstname": "Bob", "lastname": "Smith"}
]
""".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
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        firstName = try values.decode(String.self, forKey: .firstName)
        lastName = try values.decode(String.self, forKey: .lastName)
        age = try values.decode(String.self, forKey: .age)
    }

}

let decoded = try JSONDecoder().decode([Person].self, from: jsonData)
print(decoded)

问题是它在 age = try values.decode(String.self, forKey: .age) 上崩溃了。当我执行 init 函数时,它工作正常。错误是 No value associated with key age (\"age\")..

关于如何使它成为可选的并且在它不存在时不会崩溃的任何想法?出于其他原因,我也需要 init 函数,但只是举了一个简单的例子来解释发生了什么。

年龄可选:

let age: String? 

所以尝试这样解码:

let age: String? = try values.decodeIfPresent(String.self, forKey: .age)

这是我的工作。

var age: String? = nil
age = try? container.decode(String.self, forKey: .age)

希望得到帮助。

在我的模型中,我所做的是

var title: String?

...

title = try container.decode(String?.self, forKey: .age)

而不是

name = try? container.decode(String.self, forKey: .age)

例如,出于某种原因,后端会为该键传递一个数值,例如 title: 74。使用第一种方法,你会得到这样的错误信息(我为我的模型写了一个单元测试),你可以快速定位问题

但是,使用第二种方法try?,这个有用的错误消息将被隐藏,不会冒泡。你仍然会得到一个有效的解码结果 title = nil,这在大多数情况下实际上是不正确的,如果只有来自后端的 null 应该产生 nil

但是当然,如​​果你设计的是不管从后台取什么,只要type不匹配,就是一个nil。那么我觉得第一种方法应该没有问题。

iOS 有一个内置方法,仅当值存在时才读取值。

变量年龄:字符串?

age = 尝试 container.decodeIfPresent(String.self, forKey: .age)