如何解析一个 JSON 数据块而不是整个 JSON 序列

How to parse one block of JSON data instead of the entire JSON sequence

下面是用于解析 JSON api 的代码。代码有效,我能够将所有 JSON 值解析到下面的结构中,但我想知道如何只解析第一个块(?)/数组并将它们存储在结构中,以便我可以执行对它们的操作。

     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)
                print(forex.timeSeriesFX5Min)
            } catch {

                print(error)
            }

            }.resume()
    }
}

struct Root: Codable {
    let timeSeriesFX5Min: [String:Forex]

    enum CodingKeys: String, CodingKey {
        case timeSeriesFX5Min = "Time Series FX (5min)"
    }
}


    // MARK: - TimeSeriesFX5Min
    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"
        }

    }

当你发出请求时,你可能会通过回调通知谁使用请求值调用你的方法? 因此,您将创建对象或数组对象的新实例并填充结果。

如果你将在这个结构中创建你只需要你的 arrayObject 并使用 .first 然后按照这个做你的逻辑...

示例:

var newRoot: [Root] = [] 
func loadRoot() {
    Service().makeRequest() { (result, error) int
         newRoot = result.results
         print(newRoot.first)
    }
}

函数"makeRequest()"将调用您编写的方法。

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)
            print(forex.timeSeriesFX5Min)
        } catch {

            print(error)
        }

        }.resume()
}
}

我看到有两种方法可以做到这一点,第一种需要更改 Root 结构,我们需要在其中使用消息的元数据部分

struct Root: Codable {
    let metaData: [String: String]
    let timeSeriesFX5Min: [String:Forex]

    enum CodingKeys: String, CodingKey {
        case timeSeriesFX5Min = "Time Series FX (5min)"
        case metaData = "Meta Data"
    }
}

然后我们选取标有"Last Refresed"的项目并使用该值在时间序列字典中查找最新的价格条目

do {
    let forex = try JSONDecoder().decode(Root.self, from: data)
    print(forex.metaData)
    if let latestTime = forex.metaData["4. Last Refreshed"], let latestForex = forex.timeSeriesFX5Min[latestTime] {
        print(latestForex)
    }        
} catch {
    print(error)
}

另一种选择是利用时间戳以可以正确排序的格式给出这一事实,因此我们不使用元数据而是对键进行排序并选择最后一项

if let latestTime = forex.timeSeriesFX5Min.keys.sorted().last, let latestForex = forex.timeSeriesFX5Min[latestTime] {
     print(latestForex)
}