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

如何在Swift中解析包含双层嵌套无键数组的JSON文件(Xcode 10.1、macOS环境)

Swift解析嵌套动态键JSON的完整指南

嘿,刚上手Swift和JSON解析确实容易被这种嵌套结构搞晕,尤其是遇到"3600"这种动态键+双层无键数组的情况,别慌,我一步步带你搞定~

第一步:先理清JSON结构

先把你给的JSON拆解开看,这样更容易对应Swift模型:

{"result":{"3600":[[1619589600,54894.2,55019.7,54515,54660.8,104.41723222,5713178.066847375]] }, "allowance":{"cost":0, "remaining":10, "remainingPaid":9999999999, "account":"cccccc6758e98d700f" }}

  • 顶层有两个核心字段:result和allowance
  • allowance是常规键值对,很好处理
  • result里的键是动态的(比如这里的3600,可能还有其他数字键),对应的值是双层数组:外层是数组,内层数组里是一组有序的数值(时间戳、价格、成交量等)

第二步:定义Swift模型(Codable方案)

Swift的Codable协议是解析JSON的最优解,咱们针对这个结构定义对应的结构体:

1. 先处理内层的数值数组

内层数组里的元素是固定顺序的:时间戳(Int)、开盘价(Double)、最高价(Double)、最低价(Double)、收盘价(Double)、成交量(Double)、成交额(Double)。咱们可以创建一个结构体来封装这些值,手动实现Codable来解析数组:

struct CandleData: Codable {
    let timestamp: Int
    let open: Double
    let high: Double
    let low: Double
    let close: Double
    let volume: Double
    let turnover: Double
    
    // 手动实现数组转结构体的解码逻辑
    init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()
        timestamp = try container.decode(Int.self)
        open = try container.decode(Double.self)
        high = try container.decode(Double.self)
        low = try container.decode(Double.self)
        close = try container.decode(Double.self)
        volume = try container.decode(Double.self)
        turnover = try container.decode(Double.self)
    }
    
    // 如果需要编码的话也可以实现encode(to:),仅解析用可暂时忽略
}

2. 定义顶层模型

针对result的动态键,咱们用[String: [CandleData]]来表示(键是动态字符串,值是CandleData的数组);allowance直接用结构体表示:

struct Allowance: Codable {
    let cost: Int
    let remaining: Int
    let remainingPaid: Int
    let account: String
}

struct ApiResponse: Codable {
    let result: [String: [CandleData]]
    let allowance: Allowance
}

第三步:编写解析代码

假设你已经把JSON内容读取成了Data(比如从本地文件或者网络请求获取),接下来就可以解码了:

// 示例:从本地JSON文件读取数据
guard let url = Bundle.main.url(forResource: "yourJsonFile", withExtension: "json"),
      let data = try? Data(contentsOf: url) else {
    print("无法读取JSON文件")
    return
}

// 解码JSON
do {
    let decoder = JSONDecoder()
    let response = try decoder.decode(ApiResponse.self, from: data)
    
    // 拿到解析后的数据
    print("剩余免费请求次数:\(response.allowance.remaining)")
    
    // 遍历result里的动态键和对应的数据
    for (timeCycle, candleList) in response.result {
        print("当前时间周期:\(timeCycle)")
        for candle in candleList {
            print("时间戳:\(candle.timestamp),收盘价:\(candle.close)")
        }
    }
} catch {
    print("解码失败:\(error.localizedDescription)")
}

关键注意点

  • 如果result里的动态键(比如3600)是固定含义的时间周期,你也可以用枚举来映射,但如果是完全动态的,用[String: [CandleData]]是最灵活的方案
  • 内层数组的顺序一定要和JSON里的元素顺序完全对应,不然会解码失败
  • 如果JSON里的数值可能出现null,记得把模型里的属性改成可选类型(比如let timestamp: Int?)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 15:09:05