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

时间:2019-08-19 11:31:39

标签: json swift xcode swift5

我尝试对这种结构的JSON进行解码:

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

“时间序列(5分钟)”对象是对象的字典,但是当每次加载JSON时字典的键发生变化时,我都不知道如何使用可编码协议解码此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"
    }
}

我该如何以不需要预先知道键的方式编写代码,但也可以在最后获得它们以显示具有正确日期的数据。 谢谢

2 个答案:

答案 0 :(得分:0)

您只需创建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)
}

答案 1 :(得分:0)

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

// 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"
    }
}