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

Swift中遍历解码后JSON字典键,提取加密货币符号并遍历数据

解决Swift中CMC API多层嵌套JSON的遍历与模型重构问题

首先明确说:重构现有模型绝对是最优方案——你当前的模型依赖硬编码的币种ID(比如"1"对应BTC)来单独访问,扩展性极差,新加任何币种都得修改代码,完全不符合API返回的动态结构。重构后不仅能灵活处理任意返回的加密货币,还能让代码更清晰、易维护。

第一步:重构Codable模型

先修正你的模型结构,让它能完整解析CMC API返回的所有需要字段,同时适配动态的币种ID键:

// 统一表示单个加密货币的所有信息
struct CryptoCurrency: Codable {
    let id: Int64
    let name: String
    let symbol: String
    let maxSupply: Double?
    let quotes: [String:Quote]
    
    // 处理JSON蛇形命名到Swift驼峰命名的映射
    enum CodingKeys: String, CodingKey {
        case id, name, symbol, quotes
        case maxSupply = "max_supply"
    }
}

// 报价信息(比如USD)
struct Quote: Codable {
    let price: Double
    let marketCap: Double
    
    enum CodingKeys: String, CodingKey {
        case price
        case marketCap = "market_cap"
    }
}

// 顶层响应模型
struct ServerResponse: Codable {
    let data: [String:CryptoCurrency]
}

这个重构后的模型去掉了原来硬编码的btc/eth属性,直接用[String:CryptoCurrency]来接收所有返回的币种——键是CMC的币种ID,值是对应的完整信息,完美适配API的结构。

第二步:遍历与数据处理

针对你的两个需求,分别说下实现方式:

1. 提取所有加密货币符号

用map方法最简洁,一行代码就能搞定:

do {
    let decoder = JSONDecoder()
    // 全局设置自动转换蛇形命名到驼峰,省去每个模型写CodingKeys的麻烦
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let response = try decoder.decode(ServerResponse.self, from: yourJsonData)
    
    // 提取所有币种符号
    let allSymbols = response.data.values.map { $0.symbol }
    print(allSymbols) // 输出 ["BTC", "ETH", ...]
} catch {
    print("JSON解析失败: \(error.localizedDescription)")
}

2. 生成表格视图所需数据

这里可以用compactMap把原始数据转换成表格单元格专用的模型(避免直接在表格里处理原始数据,提升代码可读性):

先定义表格单元格的模型:

struct CryptoCellModel {
    let symbol: String
    let name: String
    let marketCap: String
    let maxSupply: String
}

然后转换数据:

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let response = try decoder.decode(ServerResponse.self, from: yourJsonData)
    
    let cellModels = response.data.values.compactMap { crypto -> CryptoCellModel? in
        // 确保有USD报价和maxSupply数据,避免空值崩溃
        guard let usdQuote = crypto.quotes["USD"], let maxSupply = crypto.maxSupply else {
            return nil
        }
        // 格式化数值,让表格显示更友好
        let formattedMarketCap = String(format: "$%.2f", usdQuote.marketCap)
        let formattedMaxSupply = String(format: "%.0f", maxSupply)
        
        return CryptoCellModel(
            symbol: crypto.symbol,
            name: crypto.name,
            marketCap: formattedMarketCap,
            maxSupply: formattedMaxSupply
        )
    }
    
    // 现在cellModels就是表格的数据源,可以直接赋值给tableView的dataSource数组
} catch {
    print("解析错误: \(error)")
}

如果需要逐个处理每个币种(比如做一些额外的业务逻辑,比如过滤特定排名的币种),for-in循环会更直观:

for (cryptoId, crypto) in response.data {
    print("处理币种ID: \(cryptoId)")
    if crypto.symbol == "BTC" {
        // 针对BTC的特殊处理
    }
    // 其他通用逻辑
}

总结

  • 模型重构是必须的:它解决了硬编码带来的扩展性问题,让你的代码能适配API返回的任意币种,同时符合Swift Codable的最佳实践。
  • 遍历方式选择:
    • 快速提取或转换数据用map/compactMap,代码更简洁;
    • 需要复杂逻辑处理每个元素时用for-in循环,可读性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:51:55