Таким образом, вы хотите throw
, если поле отсутствует, но продолжить, когда поле указано, но nil
.
Вам нужно реализовать пользовательскую кодировку, чтобы решить это:
enum EncodingError: Error {
case missing
}
struct Struct: Codable {
let age: Int
let name: String?
enum CodingKeys: CodingKey {
case age
case name
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
// normal decoding
age = try container.decode(Int.self, forKey: .age)
// check if key exists or throw
guard container.contains(.name) else {
throw EncodingError.missing
}
name = try container.decode(String?.self, forKey: .name)
}
}
let correctData = """
{
"age": 34,
"name": null
}
""".data(using: .utf8)!
let failData = """
{
"age": 33
}
""".data(using: .utf8)!
do {
let decoder = JSONDecoder()
let encoded = try decoder.decode(Struct.self, from: correctData) // succeeds
let fail = try decoder.decode(Struct.self, from: failData) // fails
} catch(let error) where error is EncodingError {
error
} catch {
error
}