我有一个 API 有时会以 Int 形式返回 JSON 中的特定键值(在本例中为 id
),有时会返回相同的键值作为 String。我如何使用 codable 来解析该 JSON?
struct GeneralProduct: Codable {
var price: Double!
var id: String?
var name: String!
private enum CodingKeys: String, CodingKey {
case price = "p"
case id = "i"
case name = "n"
}
init(price: Double? = nil, id: String? = nil, name: String? = nil) {
self.price = price
self.id = id
self.name = name
}
}
我不断收到此错误消息:应解码字符串但发现了一个数字
。它返回一个数字的原因是因为 id 字段为空,当 id 字段为空时,它默认返回 0 作为 ID,codable 将其标识为数字。我基本上可以忽略 ID key ,但据我所知,codable 没有给我忽略它的选项。处理此问题的最佳方法是什么?
这是 JSON。 super 简单
工作
{
"p":2.12,
"i":"3k3mkfnk3",
"n":"Blue Shirt"
}
错误 - 因为系统中没有 id,它返回 0 作为默认值,codable 显然将其视为与字符串相对的数字。
{
"p":2.19,
"i":0,
"n":"Black Shirt"
}
最佳答案
struct GeneralProduct: Codable {
var price: Double?
var id: String?
var name: String?
private enum CodingKeys: String, CodingKey {
case price = "p", id = "i", name = "n"
}
init(price: Double? = nil, id: String? = nil, name: String? = nil) {
self.price = price
self.id = id
self.name = name
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
price = try container.decode(Double.self, forKey: .price)
name = try container.decode(String.self, forKey: .name)
do {
id = try String(container.decode(Int.self, forKey: .id))
} catch DecodingError.typeMismatch {
id = try container.decode(String.self, forKey: .id)
}
}
}
let json1 = """
{
"p":2.12,
"i":"3k3mkfnk3",
"n":"Blue Shirt"
}
"""
let json2 = """
{
"p":2.12,
"i":0,
"n":"Blue Shirt"
}
"""
do {
let product = try JSONDecoder().decode(GeneralProduct.self, from: Data(json2.utf8))
print(product.price ?? "nil")
print(product.id ?? "nil")
print(product.name ?? "nil")
} catch {
print(error)
}
编辑/更新:
当您的 api 返回 0
时,您也可以简单地将 nil
分配给您的 id
:
do {
let value = try container.decode(Int.self, forKey: .id)
id = value == 0 ? nil : String(value)
} catch DecodingError.typeMismatch {
id = try container.decode(String.self, forKey: .id)
}
关于json - 使用值有时是 Int 有时是 String 的 codable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55519548/