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

久未见 提交于 2021-02-13 17:35:41

问题


I try to decode a JSON of this structure:

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

The "Time Series (5min)" Object is a dictionary of Objects, but I don't know how to decode this JSON using the Codable Protocol when the keys of the dictionary are changing whenever I load the JSON.

I tried to write some models, but whenever I try to access the dictionary I get nil.


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

How can I write my code in a way that I don't need to know the keys in advance, but also get them at the end to display the data with the correct date. Thank you


回答1:


You an simply create your Stock and Value models like,

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

There is no need for separate struct Function.

Parse your response using JSONDecoder like,

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



回答2:


you can use https://app.quicktype.io to create Codable models fast and easy. For example the following code is generated using that service with the response of that request you need. I didn't check it but should work fine.

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


来源:https://stackoverflow.com/questions/57555878/how-can-i-decode-a-dictionary-from-a-json-when-i-dont-know-the-keys-of-the-dict

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!