You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中关联类型传递Codable对象及JSON解码失败问题求助

解决Codable解码错误:数据无法读取(缺失)的问题

问题根源分析

你遇到的解码错误,本质是泛型类型的解码期望和实际JSON结构不匹配:
当你使用Resource<CurrencyModel>时,解码器会默认认为JSON根节点的quotes字段是一个包含quotes子字段的对象(也就是期望结构是{"quotes": {"quotes": {...}}}),但实际API返回的JSON里,quotes直接就是一个[String: Double]字典,没有额外嵌套。解码器找不到它期望的quotes.quotes路径,就抛出了“数据缺失”的错误。


解决方案

方案1:直接使用字典作为泛型类型(最简单)

如果你只是想把汇率数据泛型化处理,不需要额外的CurrencyModel,直接用[String: Double]作为T即可,这和你最初工作的逻辑完全一致:

// 调用方式调整为:
CurrencyLayerCommunicator().get(Resource<[String: Double]>.self) { [weak self] item in
    self?.handleResult(item)
}

方案2:调整CurrencyModel适配字典解码

如果你确实需要单独的模型封装汇率数据,可以通过自定义解码逻辑,让CurrencyModel直接解析quotes的字典结构:

struct CurrencyModel: Decodable {
    let rates: [String: Double]
    
    // 自定义解码:把传入的字典直接映射到rates属性
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        rates = try container.decode([String: Double].self)
    }
}

// 调用方式不变,现在能正确解析:
CurrencyLayerCommunicator().get(Resource<CurrencyModel>.self) { [weak self] item in
    self?.handleResult(item)
}

如果想让数据结构更友好(比如把键值对转换成单独的汇率模型),可以进一步扩展:

// 单个汇率模型
struct CurrencyRate: Decodable {
    let currencyPair: String // 比如"USDBAM"
    let rate: Double
}

// 封装所有汇率的模型
struct CurrencyModel {
    let rates: [CurrencyRate]
}

// 实现Decodable,把字典转成数组
extension CurrencyModel: Decodable {
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let quotesDict = try container.decode([String: Double].self)
        rates = quotesDict.map { CurrencyRate(currencyPair: $0.key, rate: $0.value) }
    }
}

// 调用方式依然是Resource<CurrencyModel>

关键总结

核心是让泛型参数T的解码逻辑和API返回的quotes字段类型完全匹配:要么直接用字典类型,要么让自定义模型能正确解析字典数据,避免不必要的嵌套期望。

内容的提问来源于stack exchange,提问作者MMI Test

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:26:44