我有以下struct
:
struct Recipe: Codable {
@DocumentID var id: String?
var minutes: Int?
init(id: String, minutes: Int) {
self.id = id
self.minutes = minutes
}
init(from decoder: Decoder) throws {
enum DecodingKeys: CodingKey {
case minutes
}
let container = try decoder.container(keyedBy: DecodingKeys.self)
minutes = try container.decode(Int.self, forKey: .minutes)
}
}
我从minutes
为空的源进行解码,因此我得到以下错误消息:
Error parsing response data: keyNotFound(DecodingKeys(stringValue: "minutes", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key DecodingKeys(stringValue: "minutes", intValue: nil) ("minutes").", underlyingError: nil))
然而,我认为在struct Recipe
中将minutes
标记为可选是否足以处理这种情况?我还有什么需要实施的吗?
手动实现init(from:)
时,需要对可选属性使用decodeIfPresent(_:forKey:)
变体。如果JSON数据中没有可为null的字段,而decodeIfPresent(_:forKey:)
方法只返回nil,则decode(_:forKey:)
方法会抛出错误。
试试这个:
init(from decoder: Decoder) throws {
enum DecodingKeys: CodingKey {
case minutes
}
let container = try decoder.container(keyedBy: DecodingKeys.self)
minutes = try container.decodeIfPresent(Int.self, forKey: .minutes)
}