首页 > 解决方案 > 将字符串解码并转换为可编码的双精度

问题描述

如何在 Swift 中将以下 JSON 解码为 Codable 对象?

{"USD":"12.555", "EUR":"11.555"}

这是我正在使用的结构:

struct Prices: Codable {
    var USD: Double
    var EUR: Double
    
    private enum CodingKeys: String, CodingKey {
        case USD = "USD"
        case EUR = "EUR"
    }
    
    init() {
        self.USD = 0.0
        self.EUR = 0.0
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.USD = try container.decode(Double.self, forKey: .USD)
        self.EUR = try container.decode(Double.self, forKey: .EUR)
    }
}

我得到的错误是

Error typeMismatch(Swift.Double, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "USD", intValue: nil)], debugDescription: "Expected to decode Double but found a string/data instead.", underlyingError: nil))

标签: swift

解决方案


我认为您的结构不正确,如果您想下载更多货币汇率,将难以维护,因此我建议采用不同的方法。首先创建一个用于保存货币汇率的结构

struct CurrencyRate {
    let currency: String
    let rate: Decimal?
}

然后将json解码为字典并使用map将其转换为数组CurrencyRate

var rates = [CurrencyRate]()
do {
    let result = try JSONDecoder().decode([String: String].self, from: json)
    rates = result.map { CurrencyRate(currency: $0.key, rate: Decimal(string: $0.value))}

} catch {
    print(error)
}

关于两个注意事项CurrencyRate

  • 您有两种货币的汇率,因此通常您还有另一个名为 baseCurrency 或 otherCurrency 或类似的属性,但如果该其他货币始终相同,您可以省略它。
  • 根据您的用例,为货币属性创建一种新类型也可能是个好主意,Currency

推荐阅读