使用可编码的值,有时是 Int,有时是 String

Using codable with value that is sometimes an Int and other times a String(使用可编码的值,有时是 Int,有时是 String)

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

问题描述

我有一个 API,它有时会以 Int 形式返回 JSON 中的特定键值(在本例中为 id),而有时它会以字符串形式返回相同的键值.如何使用 codable 解析该 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
    }
}

我不断收到此错误消息:应解码字符串,但找到了一个数字.它返回数字的原因是因为 id 字段为空,当 id 字段为空时,它默认返回 0 作为可编码标识为数字的 ID.我基本上可以忽略 ID 密钥,但据我所知,可编码并没有让我选择忽略它.处理此问题的最佳方法是什么?

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 时,您也可以简单地将 nil 分配给您的 id:

You can also simply assign nil to your id when your api returns 0:

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)
}

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

本文标题为:使用可编码的值,有时是 Int,有时是 String

基础教程推荐