问题
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