我有以下代码:
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函数,但我只做了一个简单的例子来解释发生了什么。
发布于 2020-06-18 01:11:23
在我的模型中,我所做的是
var title: String?
...
title = try container.decode(String?.self, forKey: .age)而不是
name = try? container.decode(String.self, forKey: .age)例如,由于某种原因,后端为该键传递了一个数值,如title: 74。使用第一种方法,您将得到如下错误消息(我为我的模型编写了一个单元测试),您可以快速定位问题

但是,使用第二个方法try?时,这个有用的错误消息将被静默,不会冒泡。如果只有后台的null会产生一个nil,那么你仍然会得到一个有效的解码结果title = nil,这在大多数情况下是不正确的。
但当然,如果您的设计是,无论从后端检索什么,只要类型不匹配,它就会是一个nil。那么我认为第一种方法应该不会有任何问题。
https://stackoverflow.com/questions/46728324
复制相似问题