Swift适配CoinMarketCap V2 API嵌套字典的Struct构建问题
解决CoinMarketCap V2 API JSON解码的Struct适配问题
嘿,我明白你的问题了——CoinMarketCap V2 API的返回结构和V1完全不一样,你之前的代码是针对数组设计的,但V2返回的是嵌套字典,所以解码失败很正常。我来帮你修正Struct和代码:
首先,咱们先搞清楚V2 API的返回结构大概是啥样的(简化版):
{ "data": { "1": { "id": 1, "name": "Bitcoin", "symbol": "BTC", "rank": 1, "quotes": { "AUD": { "price": 65000.0 } } }, "2": { // 第二个币种数据 } } }
看到没?外层是一个包含data字段的对象,data里是以币种ID为键的字典,每个值才是具体的币种信息,而不是V1那样直接返回数组。
接下来咱们修正Struct的定义,完全对应这个嵌套结构:
// 对应API返回的最外层结构 struct CoinMarketCapResponse: Decodable { let data: [String: CoinDetail] } // 对应每个币种的详细信息 struct CoinDetail: Decodable { let id: Int let name: String let symbol: String let rank: Int let quotes: Quotes } // 对应quotes字段,里面包含不同法币的价格 struct Quotes: Decodable { let AUD: Price } // 对应具体法币的价格数据 struct Price: Decodable { let price: Double }
然后修改你的数据获取代码,现在要先解码成外层的CoinMarketCapResponse,再把字典里的值转成数组:
var coins = [CoinDetail]() func getCoinData() { let jsonURL = "https://api.coinmarketcap.com/v2/ticker/?convert=AUD" guard let url = URL(string: jsonURL) else { print("Invalid URL") return } URLSession.shared.dataTask(with: url) { [unowned self] (data, response, error) in // 先处理请求错误 if let error = error { print("Request error: \(error)") return } guard let data = data else { print("No data received from API") return } do { // 先解码外层响应 let apiResponse = try JSONDecoder().decode(CoinMarketCapResponse.self, from: data) // 把字典的values转成数组,还可以按rank排序保持顺序 self.coins = Array(apiResponse.data.values).sorted { $0.rank < $1.rank } DispatchQueue.main.async { self.tableView.reloadData() } } catch { print("Decoding error: \n\(error)") print("Error details: \(error.localizedDescription)") } }.resume() }
这里几个关键的修正点:
- 新增了
CoinMarketCapResponse来对应API的外层结构,因为V2不是直接返回数组 - 修正了结构体的嵌套层级,完全匹配JSON里的
quotes -> AUD -> price结构 - 把price的类型从
String改成了Double,因为API返回的是数字类型,这样后续做价格计算更方便 - 解码后将字典的值转换成数组,还加了排序逻辑,保持币种按排名顺序排列
这样修改后,你的代码就能正确解析V2 API的数据啦!
内容的提问来源于stack exchange,提问作者Sean Slack
相关产品推荐
相关产品推荐

