使用值有时为Int且有时为String的可编码 [英] Using codable with value that is sometimes an Int and other times a String

查看:105
本文介绍了使用值有时为Int且有时为String的可编码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个API,有时会在JSON中将它作为Int返回一个特定的键值(在本例中为 id ),而有时它会返回相同的键值作为字符串。我该如何使用可编码来解析JSON?

I have an API that will sometimes return a specific key value (in this case id) in the JSON as an Int and other times it will return that same key value as a String. How do I use codable to parse that 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
    }
}

I继续收到此错误消息:预期对String进行解码,但是找到了一个数字。它返回数字的原因是因为id字段为空,并且当id字段为空时,默认返回0作为ID,可编码的ID标识为数字。我基本上可以忽略ID密钥,但是codable并不能让我选择忽略它。最好的方法是什么?

I keep getting this error message: Expected to decode String but found a number instead. The reason that it returns a number is because the id field is empty and when the id field is empty it defaults to returning 0 as an ID which codable identifies as a number. I can basically ignore the ID key but codable does not give me the option to ignore it to my knowledge. What would be the best way to handle this?

这里是JSON。这非常简单

Here is the JSON. It is super simple

工作

{
  "p":2.12,
  "i":"3k3mkfnk3",
  "n":"Blue Shirt"
}

错误-由于系统中没有id,它默认返回0,可编码的代码显然将其视为与字符串相反的数字。

Error - because there is no id in the system, it returns 0 as a default which codable obviously sees as a number opposed to string.

{
  "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 时,将code> nil 添加到您的 id

You can also simply assign nil to your id when your api returns 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)
}

这篇关于使用值有时为Int且有时为String的可编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆