如何使用 Swift Decodable 自定义解码数组的每个元素

How to Custom Decode each element of an array using Swift Decodable

我正在解码天气 JSON 响应,我想将信息传递给将解码数组的子解码器。如何在使用 Swift Decodable 解码时为每个 JSON 数组元素传递此信息?

我正在尝试在最新的 Swift 版本 (4.2) 中执行上述操作,并且我已经实现了必要的代码以成功自定义解码与阵列中使用的相同模型。我一直无法解码整个数组。

struct DataBlock: Decodable {
    /..
    let weather: [DataPoint]?

    init(from decoder: Decoder) throws {
        try self.init(from: decoder, units: .unit)
    }

    init(from decoder: Decoder, units: Units) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        /..
        let nestedDecoder = try values.superDecoder(forKey: .weather)
        self.weather = try [DataPoint(from: nestedDecoder, units: units)]
    }

    enum CodingKeys: String, CodingKey {
        /..
        case weather
    }
}

并且在 DataPoint 模型中:

init(from decoder: Decoder, units: Units) throws {
    let values = try decoder.container(keyedBy: CodingKeys.self)
    /...
    if let value = try values.decodeIfPresent(Double.self, forKey: .value) {
        self.value = Example(value: value, units: units)
    } else {
        self.value = nil
    }
    /..
}

我正在尝试解码的 JSON 结构的相关部分:

"datablock": {
    "weather": [
        {
            /..
            "value": 22.72
            /..
        }
    ]
}

我希望解码器能够通过

units

并手动解码每个数组元素。

但是我得到一个调试错误:

"Expected to decode Dictionary<String, Any> but found an array instead."

此处触发错误:

self.weather = try [DataPoint(from: nestedDecoder, units: units)]

这解决了我的问题,让我 'walkthrough' 每个 JSON 数组元素并分别解码:

struct DataBlock: Decodable {
    /..    
    init(from decoder: Decoder, units: Units) throws {
        /..
        var data = [DataPoint]()
        var dataContainer = try values.nestedUnkeyedContainer(forKey: .data)

        while !dataContainer.isAtEnd {
            let nestedDecoder = try dataContainer.superDecoder()
            let dataPoint = try DataPoint(from: nestedDecoder, units: units)
            data.append(dataPoint)
        }

        self.data = data
        /..
    }
    /..
}