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

将CoinAPI返回的JSON转换为Swift模型时遭遇格式错误的解决方案咨询

解决CoinAPI JSON转Swift模型的格式错误问题

首先,咱们先揪出最直接的错误:你请求的CoinAPI /v1/assets 接口返回的是一个数组(一堆加密资产对象的集合),但你现在的代码是尝试把它解码成单个CryptListStruct对象,这肯定会报错说格式不对,这是核心问题之一。

接下来,再看你的模型结构体,还有几个字段类型和可选性的问题——毕竟API返回的数据里有些字段可能不是所有条目都有,或者类型和你定义的不一致:

1. 修正解码对象为数组

先改请求函数里的解码逻辑,把单个对象解码改成数组解码,同时调整completion的参数类型对应数组:

func getCryptList(_ completion: @escaping ([CryptListStruct]) -> Void, _ error: @escaping (String) -> Void){
    let header: [String: String] = [:]
    self.get(url: "https://rest.coinapi.io/v1/assets/?apikey=367FB27A-371B-4DBD-AB81-E98AAFE857B2", header: header, completion: { (data) in
        do {
            guard let data = data else {
                error("No data received")
                return
            }
            let cryptList = try JSONDecoder().decode([CryptListStruct].self, from: data)
            DispatchQueue.main.async {
                completion(cryptList)
            }
        } catch let err {
            error(err.localizedDescription)
        }
    }, error: error)
}

2. 修正模型结构体的字段问题

仔细核对API返回的字段,有几个关键调整:

  • volume1MthUsd:API返回的是带小数的数值(比如12345.67),你定义成Int会解码失败,改成Double?更合适
  • 多数日期字段(比如dataQuoteStart、dataOrderbookStart等)可能在部分资产条目中缺失,要改成可选类型
  • idIcon、dataSymbolsCount这类字段也可能存在空值,同样设为可选

修改后的完整模型:

struct CryptListStruct: Codable {
    let assetID, name: String
    let typeIsCrypto: Int
    let dataQuoteStart, dataQuoteEnd, dataOrderbookStart, dataOrderbookEnd: String?
    let dataTradeStart, dataTradeEnd: String?
    let dataSymbolsCount: Int?
    let volume1HrsUsd, volume1DayUsd, volume1MthUsd: Double?
    let priceUsd: Double?
    let idIcon, dataStart, dataEnd: String?
    
    enum CodingKeys: String, CodingKey {
        case assetID = "asset_id"
        case name
        case typeIsCrypto = "type_is_crypto"
        case dataQuoteStart = "data_quote_start"
        case dataQuoteEnd = "data_quote_end"
        case dataOrderbookStart = "data_orderbook_start"
        case dataOrderbookEnd = "data_orderbook_end"
        case dataTradeStart = "data_trade_start"
        case dataTradeEnd = "data_trade_end"
        case dataSymbolsCount = "data_symbols_count"
        case volume1HrsUsd = "volume_1hrs_usd"
        case volume1DayUsd = "volume_1day_usd"
        case volume1MthUsd = "volume_1mth_usd"
        case priceUsd = "price_usd"
        case idIcon = "id_icon"
        case dataStart = "data_start"
        case dataEnd = "data_end"
    }
}

3. 额外小技巧:兼容API字段变动

如果API后续新增了未定义的字段,默认的JSONDecoder会因为遇到未知键而解码失败。你可以给解码器添加配置,忽略未知键:

let decoder = JSONDecoder()
decoder.unknownKeysEncodingStrategy = .discard // 忽略模型中未定义的键
let cryptList = try decoder.decode([CryptListStruct].self, from: data)

这样即使API返回了新字段,解码也不会失败,灵活性更高。

内容的提问来源于stack exchange,提问作者Nurjan Ababakirov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 12:52:38