使用 Codable 解码数据时出错,即使参数是可选的
Error decoding data with Codable even though parameters are optional
我有以下 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 数据中的可空字段不存在,decode(_:forKey:)
方法将抛出错误,而 decodeIfPresent(_:forKey:)
方法只是 returns nil。
试试这个:
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)
}
我有以下 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 数据中的可空字段不存在,decode(_:forKey:)
方法将抛出错误,而 decodeIfPresent(_:forKey:)
方法只是 returns nil。
试试这个:
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)
}