我有一个API,有时会id以Int的形式在JSON中返回特定的键值(在本例中为),而有时它会返回与String相同的键值。如何使用可编码解析该JSON?
id
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 } }
我不断收到此错误消息:Expected to decode String but found a number instead。它返回数字的原因是因为id字段为空,并且当id字段为空时,默认情况下返回0作为ID,可编码的ID标识为数字。我基本上可以忽略ID密钥,但是codable并不能让我选择忽略它。处理此问题的最佳方法是什么?
Expected to decode String but found a number instead
这是JSON。超级简单
加工
{ "p":2.12, "i":"3k3mkfnk3", "n":"Blue Shirt" }
错误-由于系统中没有id,因此它默认返回0,可编码的代码显然将其视为与字符串相反的数字。
{ "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) }
编辑/更新 :
您还nil可以id在api返回时简单地分配给您0:
nil
0
do { let value = try String(container.decode(Int.self, forKey: .id)) id = value == "0" ? nil : value } catch DecodingError.typeMismatch { id = try container.decode(String.self, forKey: .id) }