Swift Codable:解码动态键

问题描述

我正在尝试练习 Swift 的 Codable API。 我发送了一个网络请求,每次收到一行,如下所示,我必须处理动态密钥:

响应示例 1:

{
  "EUR": 4695.01
}

响应示例 2:

{
  "USD": 479.01
}

响应示例 3:

{
  "BTC": 4735.01
}

我试过这个方法来解析动态键:

struct ConversionResponseModel: Decodable {
    typealias destinationCurrency = String
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
    }
}

和我的获取请求:

do {
    let myResult = try JSONDecoder().decode(ConversionResponseModel.self,from: data)
                print(myResult)
            } catch {
                print(error)
            }

但我得到的结果是:ConversionResponseModel(),但不是货币价值。 听起来我错过了一些东西。请任何帮助。谢谢

解决方法

你快到了。您获得的 JSON 将返回 [String:Double] 的字典。然后你可以使用:

struct ConversionResponseModel: Decodable {
    typealias DestinationCurrency = String
    
    let currency : DestinationCurrency
    let value : Double
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let dict = try container.decode([String:Double].self)
        guard let key = dict.keys.first else {
            throw NSError(domain: "Decoder",code: 0,userInfo: [:])
        }
        currency = key
        value = dict[key] ?? -1
    }
}

注意:考虑到 Rob Napier 的评论,您可以将 Decimal 替换为 Double -- 有关详细信息,请参阅他对原始问题的评论