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

Swift中如何解析单个JSON数据块而非完整JSON序列?附现有代码

解决方案:只解析并存储第一个时间序列数据块

没问题!AlphaVantage返回的Time Series FX (5min)是一个以时间戳为键的字典,而且默认是按从新到旧的顺序排列的,所以要拿到第一个(最新的)数据块,我们可以在现有解码逻辑的基础上稍作修改,这里给你三种实用的方案:

方案1:解析完整数据后提取第一条(最简单)

保持你原有的解码代码不变,在解析完成后直接提取字典的第一个元素即可。从iOS 13/macOS 10.15开始,Swift的Dictionary会保留JSON返回的键顺序,所以first方法就能拿到最新的那条数据:

let jsonUrlString = "https://www.alphavantage.co/query?function=FX_INTRADAY&from_symbol=EUR&to_symbol=USD&interval=5min&apikey=demo"
let urlObj = URL(string: jsonUrlString)
URLSession.shared.dataTask(with: urlObj!) {(data, response, error) in
    guard let data = data else { return }
    do {
        let forex = try JSONDecoder().decode(Root.self, from: data)
        // 安全提取第一个时间序列条目
        if let firstEntry = forex.timeSeriesFX5Min.first {
            let latestTimestamp = firstEntry.key // 最新的时间戳,比如"2024-05-20 15:05:00"
            let latestForexData = firstEntry.value // 对应的汇率数据(Forex结构体实例)
            
            // 这里可以直接操作这条数据,或者存储到变量/结构体中
            print("最新时间: \(latestTimestamp)")
            print("开盘价: \(latestForexData.the1Open)")
            print("最高价: \(latestForexData.the2High)")
        }
    } catch {
        print(error)
    }
}.resume()
}

// 原有的结构体保持不变
struct Root: Codable {
    let timeSeriesFX5Min: [String:Forex]
    enum CodingKeys: String, CodingKey {
        case timeSeriesFX5Min = "Time Series FX (5min)"
    }
}

struct Forex: Codable {
    let the1Open, the2High, the3Low, the4Close: String
    enum CodingKeys: String, CodingKey {
        case the1Open = "1. open"
        case the2High = "2. high"
        case the3Low = "3. low"
        case the4Close = "4. close"
    }
}

方案2:兼容旧系统的写法(iOS 12及以下)

如果需要兼容更早的系统,由于旧版本Swift的字典不保证顺序,我们可以先对时间戳键进行排序,取最大的那个(因为时间戳字符串的字典序和时间顺序一致,最新的时间戳字符串最大):

do {
    let forex = try JSONDecoder().decode(Root.self, from: data)
    // 按时间戳降序排序,取第一个就是最新的
    let sortedTimestamps = forex.timeSeriesFX5Min.keys.sorted(by: >)
    if let latestTimestamp = sortedTimestamps.first, let latestForexData = forex.timeSeriesFX5Min[latestTimestamp] {
        // 操作最新数据
        print("最新时间: \(latestTimestamp)")
        print("收盘价: \(latestForexData.the4Close)")
    }
} catch {
    print(error)
}

方案3:封装成单独的结构体(更优雅)

如果你想专门存储这条最新数据,可以创建一个新的结构体,把时间戳和汇率数据整合在一起,方便后续统一操作:

// 新增一个结构体用于存储单条最新数据
struct LatestForexEntry: Codable {
    let timestamp: String
    let open: String
    let high: String
    let low: String
    let close: String
}

// 解码后转换为这个结构体
do {
    let forex = try JSONDecoder().decode(Root.self, from: data)
    if let firstEntry = forex.timeSeriesFX5Min.first {
        let latestEntry = LatestForexEntry(
            timestamp: firstEntry.key,
            open: firstEntry.value.the1Open,
            high: firstEntry.value.the2High,
            low: firstEntry.value.the3Low,
            close: firstEntry.value.the4Close
        )
        // 现在可以直接操作latestEntry,比如存入数组、展示到UI等
        print(latestEntry)
    }
} catch {
    print(error)
}

关键说明

  • AlphaVantage的时间序列数据默认是降序排列的,所以第一个元素就是最新的汇率数据。
  • 所有方案都用了if let安全解包,避免字典为空时出现崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:28:29