【问题标题】:Handling incrementing JSON name using Swift使用 Swift 处理递增的 JSON 名称
【发布时间】:2020-04-24 03:43:23
【问题描述】:

我有一个带有递增名称的 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 响应结构,因为它是一个公共 API,而不是我开发的东西,我只是试图从这个 API 中解析并获取值,希望这能消除混乱!

【问题讨论】:

  • @FaysalAhmed 不幸的是,api 写得不好,所以我想问一下处理 api 给你带来一些有趣的情况的最佳实践是什么。
  • 所以不用Decodable,你可以使用字典模式来解析这个JSON。
  • 您是否使用 Almofire 来获得响应?
  • @FaysalAhmed Nah 我基本上使用 URLSession.shared.dataTask(url) 加载数据并使用解码器处理它们。你如何使用字典模式来解决这个问题?
  • 你为什么不做一个api改变??你可以要求一组宠物

标签: ios json swift decode


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您可以尝试将您的数据解析为Dictionary。这样就可以得到字典的所有键了。

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

    我希望你能弄清楚你需要做什么。

    【讨论】:

      猜你喜欢
      • 2018-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多