使用Swift处理递增的JSON名称 [英] Handling incrementing JSON name using Swift
问题描述
我有一个名称递增的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屋!