使用Swift处理递增的JSON名称 [英] Handling incrementing JSON name using Swift

查看:66
本文介绍了使用Swift处理递增的JSON名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名称递增的JSON对象以进行解析,我想将输出存储到具有名称字段和pet字段列表的对象中。我通常使用JSONDecoder,因为它非常方便且易于使用,但是我不想对CodingKey进行硬编码,因为我认为这是非常不好的做法。

I have a JSON object with incrementing names to parse and I want to store the output into an object with a name field and a list of pet field. I normally use JSONDecoder as its pretty handy and easy to use, but I don't want to hard-code the CodingKey as I think it is very bad practice.

输入:

{"shopName":"KindHeartVet", "pet1":"dog","pet2":"hamster","pet3":"cat",  ...... "pet20":"dragon"}

我要存储结果的对象如下所示。

The object that I want to store the result in is something like the following.

class VetShop: NSObject, Decodable {
var shopName: String?
var petList: [String]?

private enum VetKey: String, CodingKey {
    case shopName
    case petList
}

required init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: VetKey.self)
    shopName = try? container.decode(String.self, forKey: .shopName)

    // implement storing of petList here.
}

}

我一直在苦苦挣扎的是,因为CodingKey是枚举,它是一个let常量,所以我不能修改(也不应该修改)常量,但是我需要将petList映射到 petN字段,

What I'm struggling a lot on is, as CodingKey is enum, its a let constants, so I can't modify (and shouldn't modify) a constant, but I need to map the petList to the "petN" field, where N is the incrementing number.

编辑:

我绝对不能改变API响应结构,因为它是一个公共API,而不是我开发的东西,我只是想解析并从此API获取值,希望这能消除混乱!

I definitely cannot change the API response structure because it is a public API, not something I developed, I'm just trying to parse and get the value from this API, hope this clear the confusion!

推荐答案

Codable 具有动态密钥的规定。如果您绝对无法更改获取的JSON的结构,则可以为它实现一个解码器,如下所示:

Codable has provisions for dynamic keys. If you absolutely can't change the structure of the JSON you're getting, you could implement a decoder for it like this:

struct VetShop: Decodable {
    let shopName: String
    let pets: [String]

    struct VetKeys: CodingKey {
        var stringValue: String
        var intValue: Int?
        init?(stringValue: String) {
            self.stringValue = stringValue
        }
        init?(intValue: Int) {
            self.stringValue = "\(intValue)";
            self.intValue = intValue
        }
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: VetKeys.self)
        var pets = [String]()
        var shopName = ""
        for key in container.allKeys {
            let str = try container.decode(String.self, forKey: key)
            if key.stringValue.hasPrefix("pet") {
                pets.append(str)
            } else {
                shopName = str
            }
        }
        self.shopName = shopName
        self.pets = pets
    }
}

这篇关于使用Swift处理递增的JSON名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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