我正在尝试解析此JSON:
{
"MetaData": {
"1. Information": "Daily Time Series with Splits and Dividend Events",
"2. Symbol": "AAPL",
"3. Last Refreshed": "2018-06-08",
"4. Output Size": "Compact",
"5. Time Zone": "US/Eastern"
},
"TimeSeries": {
"2018-06-08": {
"1. open": "191.1700",
"2. high": "192.0000",
"3. low": "189.7700",
"4. close": "191.7000",
"5. adjusted close": "191.7000",
"6. volume": "26656799",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0000"
},
"2018-06-07": {
"1. open": "194.1400",
"2. high": "194.2000",
"3. low": "192.3350",
"4. close": "193.4600",
"5. adjusted close": "193.4600",
"6. volume": "21347180",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0000"
},
"2018-06-06": {
"1. open": "193.6300",
"2. high": "194.0800",
"3. low": "191.9200",
"4. close": "193.9800",
"5. adjusted close": "193.9800",
"6. volume": "20933619",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0000"
},
}
}
我想遵循这样的结构:
struct Stocks: Decodable {
struct Meta: Decodable {
let info: String
let symbol: String
let last: String
let size: String
let time: String
enum CodingKeys: String, CodingKey {
case info = "1. Information"
case symbol = "2. Symbol"
case last = "3. Last Refreshed"
case size = "4. Output Size"
case time = "5. Time Zone"
}
}
struct Time: Decodable {
let date: String
let price = Prices()
struct Prices: Decodable {
var open: Int?
var high: Int?
var low: Int?
var close: Int?
enum CodingKeys: String, CodingKey {
case open = "1. open"
case high = "2. high"
case low = "3. low"
case close = "4. close"
}
}
}
let MetaData: Meta
let TimeSeries: Time
}
对于MetaData部分,它运行良好。 但是对于时间序列部分,我不知道如何跳过日期而不仅仅是遍历TimeSeries数据。
我想知道是否有一种方法可以将此部分映射到结构:
"TimeSeries": {
"2018-06-08": {
"1. open": "191.1700",
"2. high": "192.0000",
"3. low": "189.7700",
"4. close": "191.7000",
"5. adjusted close": "191.7000",
"6. volume": "26656799",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0000"
},
"2018-06-07": {
"1. open": "194.1400",
"2. high": "194.2000",
"3. low": "192.3350",
"4. close": "193.4600",
"5. adjusted close": "193.4600",
"6. volume": "21347180",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0000"
},
"2018-06-06": {
"1. open": "193.6300",
"2. high": "194.0800",
"3. low": "191.9200",
"4. close": "193.9800",
"5. adjusted close": "193.9800",
"6. volume": "20933619",
"7. dividend amount": "0.0000",
"8. split coefficient": "1.0000"
},
}
}
问题似乎是不断变化的日期键-如何将它们映射到结构上?
答案 0 :(得分:1)
首先Prices
中的值是String
,请注意用双引号引起来。
并且即使这些值是数字,它们也将是Double
,请注意小数点。
我的建议是编写一个自定义初始化程序,该初始化程序将键TimeSeries
的值解码为字典,并将date
键值对放入Price
结构中(我使用的是单数形式)形成)。最后,该数组按date
struct Stocks: Decodable {
enum CodingKeys: String, CodingKey { case timeSeries = "TimeSeries", metaData = "MetaData"}
struct Meta: Decodable {
let info, symbol, last, size, time: String
enum CodingKeys: String, CodingKey {
case info = "1. Information"
case symbol = "2. Symbol"
case last = "3. Last Refreshed"
case size = "4. Output Size"
case time = "5. Time Zone"
}
}
struct Price: Decodable {
var date = ""
let open, high, low, close: String
enum CodingKeys: String, CodingKey {
case open = "1. open"
case high = "2. high"
case low = "3. low"
case close = "4. close"
}
}
let metaData: Meta
let prices : [Price]
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
metaData = try container.decode(Meta.self, forKey: .metaData)
let timeData = try container.decode([String:Price].self, forKey: .timeSeries)
prices = timeData.map({ (key, value) -> Price in
var newPrice = value
newPrice.date = key
return newPrice
}).sorted { $0.date < $1.date }
}
}