使用 Swift 处理递增的 JSON 名称
Handling incrementing JSON name using Swift
我有一个 JSON 对象,其名称递增以供解析,我想将输出存储到一个具有名称字段和宠物字段列表的对象中。我通常使用 JSONDecoder,因为它非常方便且易于使用,但我不想对 CodingKey 进行硬编码,因为我认为这是非常糟糕的做法。
输入:
{"shopName":"KindHeartVet", "pet1":"dog","pet2":"hamster","pet3":"cat", ...... "pet20":"dragon"}
我想要存储结果的对象如下所示。
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" 字段,其中 N 是递增数字。
编辑:
我绝对不能更改 API 响应结构,因为它是 public API,不是我开发的东西,我只是试图解析并从中获取值API,希望这能消除困惑!
您可以尝试将您的数据解析为 Dictionary
。这样就可以得到字典的所有key
let url = URL(string: "YOUR_URL_HERE")
URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) in
guard let data = data, error == nil else { return }
do {
let dics = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! Dictionary<String, Any>
let keys = [String](dics.keys)
print(keys) // You have the key list
print(dics[keys[0]]) // this will print the first value
} catch let error as NSError {
print(error)
}
}).resume()
我希望你能弄清楚你需要做什么。
Codable
提供动态键。如果你绝对不能改变你得到的 JSON 的结构,你可以像这样为它实现一个解码器:
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
}
}
我有一个 JSON 对象,其名称递增以供解析,我想将输出存储到一个具有名称字段和宠物字段列表的对象中。我通常使用 JSONDecoder,因为它非常方便且易于使用,但我不想对 CodingKey 进行硬编码,因为我认为这是非常糟糕的做法。
输入:
{"shopName":"KindHeartVet", "pet1":"dog","pet2":"hamster","pet3":"cat", ...... "pet20":"dragon"}
我想要存储结果的对象如下所示。
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" 字段,其中 N 是递增数字。
编辑:
我绝对不能更改 API 响应结构,因为它是 public API,不是我开发的东西,我只是试图解析并从中获取值API,希望这能消除困惑!
您可以尝试将您的数据解析为 Dictionary
。这样就可以得到字典的所有key
let url = URL(string: "YOUR_URL_HERE")
URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) in
guard let data = data, error == nil else { return }
do {
let dics = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! Dictionary<String, Any>
let keys = [String](dics.keys)
print(keys) // You have the key list
print(dics[keys[0]]) // this will print the first value
} catch let error as NSError {
print(error)
}
}).resume()
我希望你能弄清楚你需要做什么。
Codable
提供动态键。如果你绝对不能改变你得到的 JSON 的结构,你可以像这样为它实现一个解码器:
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
}
}