当我不知道字典的键时,如何从 JSON 解码字典?

How can I decode a dictionary from a JSON when I don't know the keys of the dictionary?

我尝试解码 JSON 这个结构:

https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=MSFT&interval=5min&apikey=demo

"Time Series (5min)" 对象是对象的字典,但是当我加载 JSON.

我尝试编写一些模型,但每当我尝试访问字典时,我都没有得到。


struct stock: Decodable{
    let function: Function?
    enum CodingKeys: String, CodingKey {
        case function = "Time Series (5min)"
    }
}

struct Function: Decodable{
    let values: [String:Value]
}

struct Value: Decodable{
    let open: String
    let heigh: String
    let low: String
    let close: String
    let volume: String
    enum CodingKeys: String, CodingKey{
        case open = "1.open"
        case heigh = "2. heigh"
        case low = "3. low"
        case close = "4.close"
        case volume = "5.volume"
    }
}

我怎样才能以一种不需要提前知道密钥的方式编写我的代码,而且还可以在最后获取它们以显示具有正确日期的数据。 谢谢

您只需创建 StockValue 模型,例如,

struct Stock: Decodable {
    let timeSeries: [String:Value]

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

struct Value: Decodable {
    let open: String
    let high: String
    let low: String
    let close: String
    let volume: String

    enum CodingKeys: String, CodingKey{
        case open = "1. open"
        case high = "2. high"
        case low = "3. low"
        case close = "4. close"
        case volume = "5. volume"
    }
}

不需要单独struct Function

使用 JSONDecoder 解析您的回复,例如,

do{
    let response = try JSONDecoder().decode(Stock.self, from: data)
    print(response)
} catch {
    print(error)
}

您可以使用 https://app.quicktype.io 快速轻松地创建 Codable 模型。例如,以下代码是使用该服务生成的,并响应您需要的请求。我没有检查,但应该可以正常工作。

// This file was generated from JSON Schema using quicktype, do not modify it directly.
// To parse the JSON, add this file to your project and do:
//
//   let stock = try? JSONDecoder().decode(Stock.self, from: jsonData)

import Foundation

// MARK: - Stock
struct Stock: Codable {
    let metaData: MetaData
    let timeSeries5Min: [String: TimeSeries5Min]

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

// MARK: - MetaData
struct MetaData: Codable {
    let the1Information, the2Symbol, the3LastRefreshed, the4Interval: String
    let the5OutputSize, the6TimeZone: String

    enum CodingKeys: String, CodingKey {
        case the1Information = "1. Information"
        case the2Symbol = "2. Symbol"
        case the3LastRefreshed = "3. Last Refreshed"
        case the4Interval = "4. Interval"
        case the5OutputSize = "5. Output Size"
        case the6TimeZone = "6. Time Zone"
    }
}

// MARK: - TimeSeries5Min
struct TimeSeries5Min: Codable {
    let the1Open, the2High, the3Low, the4Close: String
    let the5Volume: String

    enum CodingKeys: String, CodingKey {
        case the1Open = "1. open"
        case the2High = "2. high"
        case the3Low = "3. low"
        case the4Close = "4. close"
        case the5Volume = "5. volume"
    }
}