依赖于 JSON 数据的结构
Posted
技术标签:
【中文标题】依赖于 JSON 数据的结构【英文标题】:Structs depending on JSON data 【发布时间】:2021-01-10 03:26:16 【问题描述】:我目前正在使用金融市场 API,我可以在其中获取 JSON 数据作为单个股票代码/报价或批量。
如果我知道我要提前从 API 请求什么股票代码,我就能够解码 JSON 数据。
我正在苦苦挣扎的是如何写我的structs
,以便我可以解码用户选择的任何股票代码。
例如,在开发中,我知道我想在 AAPL 上请求股票数据,所以我会写适当的 struct
(如下),但可以说,在实际部署中,我想看看在 TSLA 股票数据中,在这种情况下,我不会编写适当的 TSLA struct
,因为我只有为 AAPL 编写的 struct
,因此会收到错误。
有没有办法编写某种动态的struct
或使用 Swift 库来帮助解决这个问题?
我将在下面发布 JSON 数据的 sn-p 和我的struct
。
"AAPL":
"quote":
"symbol":"AAPL",
"companyName":"Apple, Inc.",
"primaryExchange":"NASDAQ",
"calculationPrice":"close",
"open":112.67,
"openTime":1600781401038,
"openSource":"official",
"close":111.81,
"closeTime":1600804800589,
"closeSource":"official",
"high":112.86,
"highTime":1600819199980,
"highSource":"15 minute delayed price",
"low":109.16,
"lowTime":1600786957213,
"lowSource":"15 minute delayed price",
"latestPrice":111.81,
"latestSource":"Close",
"latestTime":"September 22, 2020",
"latestUpdate":1600804800589,
"latestVolume":183055373,
"iexRealtimePrice":111.545,
"iexRealtimeSize":56,
"iexLastUpdated":1600806216383,
"delayedPrice":110.6,
"delayedPriceTime":1600819199980,
"oddLotDelayedPrice":127.67,
"oddLotDelayedPriceTime":1600807552123,
"extendedPrice":110.6,
"extendedChange":-1.21,
"extendedChangePercent":-0.01082,
"extendedPriceTime":1600819199980,
"previousClose":110.08,
"previousVolume":195713815,
"change":1.73,
"changePercent":0.01572,
"volume":183055373,
"iexMarketPercent":0.007153872636301017,
"iexVolume":1303096,
"avgTotalVolume":196415720,
"iexBidPrice":0,
"iexBidSize":0,
"iexAskPrice":0,
"iexAskSize":0,
"iexOpen":null,
"iexOpenTime":null,
"iexClose":111.8,
"iexCloseTime":1600804792007,
"marketCap":1938483513000,
"peRatio":33.69,
"week52High":137.98,
"week52Low":53.15,
"ytdChange":0.50212,
"lastTradeTime":1600804799962,
"isUSMarketOpen":false
,
"FB":
"quote":
"symbol":"FB",
"companyName":"Facebook, Inc.",
"primaryExchange":"NASDAQ",
"calculationPrice":"close",
"open":253.31,
"openTime":1600781400128,
"openSource":"official",
"close":254.75,
"closeTime":1600804800789,
"closeSource":"official",
"high":255.32,
"highTime":1600819191691,
"highSource":"15 minute delayed price",
"low":248.22,
"lowTime":1600787261157,
"lowSource":"15 minute delayed price",
"latestPrice":254.75,
"latestSource":"Close",
"latestTime":"September 22, 2020",
"latestUpdate":1600804800789,
"latestVolume":30401995,
"iexRealtimePrice":254.695,
"iexRealtimeSize":100,
"iexLastUpdated":1600804797803,
"delayedPrice":253.8,
"delayedPriceTime":1600819191691,
"oddLotDelayedPrice":254.74,
"oddLotDelayedPriceTime":1600804799413,
"extendedPrice":253.8,
"extendedChange":-0.95,
"extendedChangePercent":-0.00373,
"extendedPriceTime":1600819191691,
"previousClose":248.15,
"previousVolume":24709378,
"change":6.6,
"changePercent":0.0266,
"volume":30401995,
"iexMarketPercent":0.025296103101128724,
"iexVolume":769052,
"avgTotalVolume":25154911,
"iexBidPrice":0,
"iexBidSize":0,
"iexAskPrice":0,
"iexAskSize":0,
"iexOpen":null,
"iexOpenTime":null,
"iexClose":254.695,
"iexCloseTime":1600804797803,
"marketCap":725735292113,
"peRatio":30.89,
"week52High":304.67,
"week52Low":137.1,
"ytdChange":0.241301,
"lastTradeTime":1600804800789,
"isUSMarketOpen":false
----
struct iexTicker: Decodable
let AAPL: iexQuote
let FB: iexQuote
struct iexQuote: Decodable
let quote: iexData
struct iexData: Decodable
let symbol: String?
let companyName: String?
let primaryExchange: String?
let calculationPrice: String?
let open: Double?
let openTime: Double?
let openSource: String?
let close: Double?
let closeTime: Double?
let closeSource: String?
let high: Double?
let highTime: Double?
let low: Double?
let lowTime: Double?
let lowSource: String?
let latestPrice: Double?
let latestSource: String?
let latestTime: String?
let latestUpdate: Double?
let latestVolume: Double?
let iexRealtimePrice: Double?
let iexRealtimeSize: Double?
let iexLastUpdated: Double?
let delayedPrice: Double?
let delayedPriceTime: Double?
let oddLotDelayedPrice: Double?
let oddLotDelayedPriceTime: Double?
let extendedPrice: Double?
let extendedChange: Double?
let extendedChangePercent: Double?
let extendedPriceTime: Double?
let previousClose: Double?
let previousVolume: Double?
let change: Double?
let changePercent: Double?
let volume: Double?
let iexMarketPercent: Double?
let iexVolume: Double?
let avgTotalVolume: Double?
let iexBidPrice: Double?
let iexBidSize: Double?
let iexAskPrice: Double?
let iexAskSize: Double?
let iexOpen: Double?
let iexOpenTime: Double?
let iexClose: Double?
let iexCloseTime: Double?
let marketCap: Double?
let peRatio: Double?
let week52High: Double?
let week52Low: Double?
let ytdChange: Double?
let lastTradeTime: Double?
let isUSMarketOpen: Bool?
【问题讨论】:
AAPL 和 TSLA 的结构不一样吗?看起来您只需要解码[TickerName: IEXQuote]
类型的字典(其中TickerName
只是String
的别名)
我认为您缺少 JSON
的某些部分。我怀疑开头应该是 "APPL": "quote": "symbol":"AAPL", ... , "FB": ...
,而您离开了最初的 "APPL":
部分。
【参考方案1】:
有什么办法可以写出某种动态结构
没有。但是您可以为每种类型的 JSON 编写不同的结构,然后将数据吸入一些更通用的类型。例如,如果您有两个结构,Ticker1Data 和 Ticker2Data,那么您可以有一个枚举 AnyTicker
,其案例具有 Ticker1Data 和 Ticker2Data 作为关联类型:
enum AnyTicker
case ticker1(Ticker1Data)
case ticker2(Ticker2Data)
现在单个 AnyTicker 实例将保存 Ticker1Data 或 Ticker2Data。一旦你有一个枚举实例,你就可以找出它是什么情况,现在关联的数据自动属于正确的类型。
【讨论】:
以上是关于依赖于 JSON 数据的结构的主要内容,如果未能解决你的问题,请参考以下文章