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

Swift Codable:如何将键为交易对的JSON解码为带name属性的结构体

解决Swift中动态键JSON转带名称属性结构体的问题

你收到的JSON格式是把交易对名称作为字典的键,而你需要把这个键赋值给Pair结构体的name属性,直接用默认的Codable解码肯定行不通——毕竟默认解码逻辑会把键和结构体的固定属性绑定,而这里的键是动态变化的。下面给你两种实用的解决方案:

方法一:先解码为字典再转换(直观易维护)

这种方法先把JSON解码成字典,再遍历字典生成Pair实例,步骤清晰易懂:

  1. 保留你的Pair结构体,同时定义一个辅助结构体承载每个交易对的具体数据:
struct Pair: Codable { 
    let name: String
    let last: String
    let percentChange: String
    let baseVolume: String
}

// 辅助结构体,对应JSON里每个键的value部分
private struct PairData: Codable {
    let last: String
    let percentChange: String
    let baseVolume: String
}
  1. 执行解码与转换:
// 假设你已经获取到服务器返回的JSON Data
let jsonData: Data = // 你的数据来源

do {
    // 先解码成[String: PairData]类型,键就是交易对名称
    let pairDictionary = try JSONDecoder().decode([String: PairData].self, from: jsonData)
    
    // 遍历字典,把键作为name,和数据一起生成Pair数组
    let pairs = pairDictionary.map { tradePairName, data in
        Pair(
            name: tradePairName,
            last: data.last,
            percentChange: data.percentChange,
            baseVolume: data.baseVolume
        )
    }
    
    // 现在pairs就是你需要的结果了
    print(pairs)
} catch {
    print("解码出错啦: \(error.localizedDescription)")
}

方法二:自定义解码逻辑(封装性更强)

如果需要更优雅的封装,可以自定义一个响应结构体,把解码逻辑藏在内部,调用时直接拿到[Pair]:

struct Pair: Codable { 
    let name: String
    let last: String
    let percentChange: String
    let baseVolume: String
}

private struct PairData: Codable {
    let last: String
    let percentChange: String
    let baseVolume: String
}

// 自定义响应结构体,处理动态键解码
struct PairsResponse: Codable {
    let pairs: [Pair]
    
    init(from decoder: Decoder) throws {
        // 创建支持动态键的容器
        let keyedContainer = try decoder.container(keyedBy: DynamicCodingKey.self)
        var pairsArray = [Pair]()
        
        // 遍历所有动态键
        for key in keyedContainer.allKeys {
            let data = try keyedContainer.decode(PairData.self, forKey: key)
            let pair = Pair(
                name: key.stringValue,
                last: data.last,
                percentChange: data.percentChange,
                baseVolume: data.baseVolume
            )
            pairsArray.append(pair)
        }
        
        self.pairs = pairsArray
    }
    
    // 自定义动态编码键,处理字符串类型的键
    private struct DynamicCodingKey: CodingKey {
        let stringValue: String
        init?(stringValue: String) {
            self.stringValue = stringValue
        }
        
        let intValue: Int?
        init?(intValue: Int) {
            self.intValue = intValue
            self.stringValue = String(intValue)
        }
    }
}

// 使用方式
do {
    let response = try JSONDecoder().decode(PairsResponse.self, from: jsonData)
    print(response.pairs)
} catch {
    print("解码失败: \(error)")
}

两种方法都能解决你的问题,第一种更适合简单场景,第二种适合需要重复处理这种JSON格式的情况,按需选择即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:56:00