【问题标题】:Swift 4 decodable nested json with random key attributes具有随机键属性的 Swift 4 可解码嵌套 json
【发布时间】:2017-12-02 11:25:39
【问题描述】:

我在解码 json 时遇到问题。我已经学习了很多教程,但没有使用复杂的 json 结构。为简单起见,我将代码最小化并使用 Dog 作为示例。

在下面的 json 中,我主要只对 Dog 结构感兴趣。 json“数据”属性包含随机狗名。所以我不能使用编码键,因为我不知道属性名称。

{
     "Response": "success"
     "BaseLinkUrl": "https://wwww.example.com",
     "Data": {
         "Max": {
             "name": "Max",
             "breed": "Labrador"
         },
         "Rocky": {
             "name": "Rocky",
             "breed": "Labrador"
         },
         ...
    }
}

我有以下结构:

struct DogResponse : Decodable {
    let data : DogResponseData

    enum CodingKeys: String, CodingKey {
        case data = "Data"
    }
}

struct DogResponseData: Decodable {
    let dog: Dog //this is a random variable name

    enum CodingKeys: String, CodingKey {
        case dog = "??random_variable_dog_name??"
    }
}

struct Dog: Decodable {
    let name: String
    let type: String

    enum CodingKeys: String, CodingKey {
        case name
        case type = "breed"
    }
}

收集 Dog 结构体:

let dogResponse = try JSONDecoder().decode(DogResponse.self, from: data)
print(dogResponse)

我需要在“DogResponseData”结构中做什么才能快速识别包含我的 Dog 结构的随机变量?

【问题讨论】:

    标签: json swift4 decodable


    【解决方案1】:

    一种可能的解决方案是编写一个自定义初始化程序来将字典解码为[String:Dog] 并将值映射到一个数组

    struct Dog : Decodable {
        let name : String
        let breed : String
    }
    
    struct DogResponse : Decodable {
        let dogs : [Dog]
    
        private enum CodingKeys: String, CodingKey {
            case data = "Data"
        }
    
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            let data = try values.decode([String : Dog].self, forKey: .data)
            dogs = Array(data.values)
        }
    }
    

    let dogResponse = try JSONDecoder().decode(DogResponse.self, from: data)
    print(dogResponse.dogs)
    

    ================================================ ==============================

    或者如果你想保持字典结构更短

    struct Dog : Decodable {
        let name : String
        let breed : String
    }
    
    struct DogResponse : Decodable {
        let dogs : [String : Dog]
    
        private enum CodingKeys: String, CodingKey {
            case dogs = "Data"
        }
    }
    

    【讨论】:

    • 谢谢!这两种选择都像一个魅力!我现在看到我什至不必处理随机密钥。
    • 因为随机密钥总是等于name,所以它是多余的。
    • 如果随机键的值中没有提供名称怎么办?如何捕获键值以将其分配为狗名?
    【解决方案2】:

    值得注意的是CodingKey 是一个协议,不一定是enum。所以你可以把它设为struct,它会接受你扔给它的任何随机字符串值。

    【讨论】:

      猜你喜欢
      • 2018-07-02
      • 1970-01-01
      • 1970-01-01
      • 2019-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多