Ios 如何用Swift中的Decodable解析JSON元素。这样做时我会收到错误
上面是我调用的API JSON响应。下面是用swift写的可解码代码Ios 如何用Swift中的Decodable解析JSON元素。这样做时我会收到错误,ios,json,swift,Ios,Json,Swift,上面是我调用的API JSON响应。下面是用swift写的可解码代码 { "optionChain": { "result": [ { "underlyingSymbol": "AAPL", "expirationDates": [ 1606435200, 165
{
"optionChain": {
"result": [
{
"underlyingSymbol": "AAPL",
"expirationDates": [
1606435200,
1655424000,
1663286400,
1674172800
],
"strikes": [
55,
60,
65,
70,
75,
80,
85,
90,
95,
96,
97,
98,
99,
100,
101,
102,
103,
104,
105,
106,
107,
108,
109,
110,
111,
112,
113,
114,
115,
116,
131,
132,
133,
155,
160,
165,
170,
175
],
"hasMiniOptions": false,
"quote": {
"language": "en-US",
"region": "US",
"quoteType": "EQUITY",
"quoteSourceName": "Nasdaq Real Time Price",
"triggerable": true,
"currency": "USD",
"firstTradeDateMilliseconds": 345479400000,
"priceHint": 2,
"regularMarketChange": -2.2599945,
"regularMarketChangePercent": -1.9260223,
"regularMarketTime": 1606152628,
"regularMarketPrice": 115.08,
"regularMarketDayHigh": 117.62,
"regularMarketDayRange": "113.8 - 117.62",
"regularMarketDayLow": 113.8,
"regularMarketVolume": 66403356,
"regularMarketPreviousClose": 117.34,
"bid": 114.79,
"ask": 114.78,
"bidSize": 9,
"askSize": 10,
"fullExchangeName": "NasdaqGS",
"financialCurrency": "USD",
"regularMarketOpen": 117.18,
"averageDailyVolume3Month": 150914918,
"averageDailyVolume10Day": 78477066,
"fiftyTwoWeekLowChange": 61.9275,
"fiftyTwoWeekLowChangePercent": 1.165091,
"fiftyTwoWeekRange": "53.1525 - 137.98",
"fiftyTwoWeekHighChange": -22.899994,
"fiftyTwoWeekHighChangePercent": -0.16596605,
"fiftyTwoWeekLow": 53.1525,
"fiftyTwoWeekHigh": 137.98,
"dividendDate": 1605139200,
"earningsTimestamp": 1603989000,
"earningsTimestampStart": 1611658740,
"earningsTimestampEnd": 1612180800,
"trailingAnnualDividendRate": 0.795,
"trailingPE": 35.085365,
"trailingAnnualDividendYield": 0.0067751836,
"epsTrailingTwelveMonths": 3.28,
"epsForward": 4.33,
"epsCurrentYear": 3.96,
"priceEpsCurrentYear": 29.060606,
"sharesOutstanding": 17102499840,
"bookValue": 3.849,
"fiftyDayAverage": 116.774574,
"fiftyDayAverageChange": -1.6945724,
"fiftyDayAverageChangePercent": -0.014511485,
"twoHundredDayAverage": 104.00763,
"twoHundredDayAverageChange": 11.072372,
"twoHundredDayAverageChangePercent": 0.10645731,
"marketCap": 1956567187456,
"forwardPE": 26.577368,
"priceToBook": 29.898676,
"sourceInterval": 15,
"exchangeDataDelayedBy": 0,
"tradeable": false,
"exchange": "NMS",
"shortName": "Apple Inc.",
"longName": "Apple Inc.",
"marketState": "REGULAR",
"messageBoardId": "finmb_24937",
"exchangeTimezoneName": "America/New_York",
"exchangeTimezoneShortName": "EST",
"gmtOffSetMilliseconds": -18000000,
"market": "us_market",
"esgPopulated": false,
"displayName": "Apple",
"symbol": "AAPL"
},
"options": [
{
"expirationDate": 1606435200,
"hasMiniOptions": false,
"calls": [
{
"contractSymbol": "AAPL201127C00165000",
"strike": 165,
"currency": "USD",
"lastPrice": 0.01,
"change": 0,
"percentChange": 0,
"volume": 1,
"openInterest": 156,
"bid": 0,
"ask": 0.01,
"contractSize": "REGULAR",
"expiration": 1606435200,
"lastTradeDate": 1605731100,
"impliedVolatility": 1.000005,
"inTheMoney": false
},
{
"contractSymbol": "AAPL201127C00170000",
"strike": 170,
"currency": "USD",
"lastPrice": 0.01,
"change": 0,
"percentChange": 0,
"volume": 11,
"openInterest": 353,
"bid": 0,
"ask": 0.01,
"contractSize": "REGULAR",
"expiration": 1606435200,
"lastTradeDate": 1605731115,
"impliedVolatility": 1.0625046875000002,
"inTheMoney": false
},
{
"contractSymbol": "AAPL201127C00175000",
"strike": 175,
"currency": "USD",
"lastPrice": 0.01,
"change": 0,
"percentChange": 0,
"volume": 5,
"openInterest": 259,
"bid": 0,
"ask": 0.01,
"contractSize": "REGULAR",
"expiration": 1606435200,
"lastTradeDate": 1606150652,
"impliedVolatility": 1.15625421875,
"inTheMoney": false
}
],
"puts": [
{
"contractSymbol": "AAPL201127P00134000",
"strike": 134,
"currency": "USD",
"lastPrice": 14.2,
"change": 0,
"percentChange": 0,
"volume": 4,
"openInterest": 133,
"bid": 19.1,
"ask": 19.35,
"contractSize": "REGULAR",
"expiration": 1606435200,
"lastTradeDate": 1605632020,
"impliedVolatility": 0.831056376953125,
"inTheMoney": true
},
{
"contractSymbol": "AAPL201127P00135000",
"strike": 135,
"currency": "USD",
"lastPrice": 21.05,
"change": 3.869999,
"percentChange": 22.526186,
"volume": 38,
"openInterest": 258,
"bid": 20.35,
"ask": 20.5,
"contractSize": "REGULAR",
"expiration": 1606435200,
"lastTradeDate": 1606148156,
"impliedVolatility": 0.96679720703125,
"inTheMoney": true
},
{
"contractSymbol": "AAPL201127P00138000",
"strike": 138,
"currency": "USD",
"lastPrice": 19.41,
"change": 0,
"percentChange": 0,
"openInterest": 1,
"bid": 23.1,
"ask": 23.25,
"contractSize": "REGULAR",
"expiration": 1606435200,
"lastTradeDate": 1605819053,
"impliedVolatility": 0.91992267578125,
"inTheMoney": true
},
{
"contractSymbol": "AAPL201127P00140000",
"strike": 140,
"currency": "USD",
"lastPrice": 21.19,
"change": 0,
"percentChange": 0,
"volume": 24,
"openInterest": 53,
"bid": 25.2,
"ask": 25.35,
"contractSize": "REGULAR",
"expiration": 1606435200,
"lastTradeDate": 1605818102,
"impliedVolatility": 1.0429735351562504,
"inTheMoney": true
},
{
"contractSymbol": "AAPL201127P00145000",
"strike": 145,
"currency": "USD",
"lastPrice": 26.85,
"change": 0,
"percentChange": 0,
"volume": 1,
"openInterest": 55,
"bid": 30.2,
"ask": 30.35,
"contractSize": "REGULAR",
"expiration": 1606435200,
"lastTradeDate": 1605892788,
"impliedVolatility": 1.185550947265625,
"inTheMoney": true
},
{
"contractSymbol": "AAPL201127P00175000",
"strike": 175,
"currency": "USD",
"lastPrice": 57.13,
"change": 0,
"percentChange": 0,
"volume": 2,
"openInterest": 2,
"bid": 60.15,
"ask": 60.25,
"contractSize": "REGULAR",
"expiration": 1606435200,
"lastTradeDate": 1605798274,
"impliedVolatility": 1.822266513671875,
"inTheMoney": true
}
]
}
]
}
],
"error": null
}}
我将这些代码中的可分解性称为:
struct Something: Decodable
{
let optionChain: OptionChain
let error: String
}
struct OptionChain: Decodable
{
let result: [ResultElement]
}
struct ResultElement: Decodable
{
let underlyingSymbol: String
let expirationDates: [Int]
let strikes: [Int]
let hasMiniOptions: Bool
let quote: [quoteElement]
let options: [optionsElement]
}
struct quoteElement: Decodable
{
let language: String
let region: String
let quoteType: String
let quoteSourceName: String
let triggerable: Bool
let currency: String
let firstTradeDateMilliseconds: Int
let priceHint: Int
let regularMarketChange: Int
let regularMarketChangePercent: Int
let regularMarketTime: Int
let regularMarketPrice: Int
let regularMarketDayHigh: Int
let regularMarketDayRange: String
let regularMarketDayLow: Int
let regularMarketVolume: Int
let regularMarketPreviousClose: Int
let bid: Int
let ask: Int
let bidSize: Int
let askSize: Int
let fullExchangeName: String
let financialCurrency: String
let regularMarketOpen: Int
let averageDailyVolume3Month: Int
let averageDailyVolume10Day: Int
let fiftyTwoWeekLowChange: Int
let fiftyTwoWeekLowChangePercent: Int
let fiftyTwoWeekRange: String
let fiftyTwoWeekHighChange: Int
let fiftyTwoWeekHighChangePercent: Int
let fiftyTwoWeekLow: Int
let fiftyTwoWeekHigh: Int
let dividendDate: Int
let earningsTimestamp: Int
let earningsTimestampStart: Int
let earningsTimestampEnd: Int
let trailingAnnualDividendRate: Int
let trailingPE: Int
let trailingAnnualDividendYield: Int
let epsTrailingTwelveMonths: Int
let epsForward: Int
let epsCurrentYear: Int
let priceEpsCurrentYear: Int
let sharesOutstanding: Int
let bookValue: Int
let fiftyDayAverage: Int
let fiftyDayAverageChange: Int
let fiftyDayAverageChangePercent: Int
let twoHundredDayAverage: Int
let twoHundredDayAverageChange: Int
let twoHundredDayAverageChangePercent: Int
let marketCap: Int
let forwardPE: Int
let priceToBook: Int
let sourceInterval: Int
let exchangeDataDelayedBy: Int
let tradeable: Bool
let exchange: String
let shortName: String
let longName: String
let marketState: String
let messageBoardId: String
let exchangeTimezoneName: String
let exchangeTimezoneShortName: String
let gmtOffSetMilliseconds: Int
let market: String
let esgPopulated: Bool
let displayName: String
let symbol: String
}
struct optionsElement: Decodable
{
let expirationDate: Int
let hasMiniOptions: Bool
let calls: [callPutElement]
let puts: [callPutElement]
}
struct callPutElement: Decodable
{
let contractSymbol: String
let strike: Int
let currency: String
let lastPrice: Int
let change: Int
let percentChange: Int
let volume: Int
let openInterest: Int
let bid: Int
let ask: Int
let contractSize: String
let expiration: Int
let lastTradeDate: Int
let impliedVolatility: Int
let inTheMoney: Bool
}
let request=NSMutableURLRequest(url:NSURL(string:urlTicker)!作为url,
cachePolicy:.useProtocolCachePolicy,
timeoutInterval:10.0)
request.httpMethod=“GET”
request.allHTTPHeaderFields=标题
让session=URLSession.shared
让dataTask=session.dataTask(其中:request作为URLRequest,completionHandler:{(数据,响应,错误)->Void in
如果(错误!=nil)
{
打印(错误)
}
其他的
{
让httpResponse=响应为?HTTPURLResponse
做
{
让jsonString=“{…}”
让jsonData=jsonString.data(使用:.utf8)!
let decoder=JSONDecoder()
let something=尝试decoder.decode(something.self,from:jsonData)
打印(something.optionChain.result.map{$0.underyingsymbol})
//让myJSON=try JSONSerialization.jsonObject(带:data!,选项:.allowFragments)作为?[String:Any]
//让likes=myJSON![“optionChain”]as?数组
}
抓住
{
打印(“JSONSerialization错误:”,错误)
}
//打印(httpResponse)
//打印(myJSON[“Strokes”]为!字符串)
}
})
dataTask.resume()
我进入catch语句,错误是:
SONSerialization错误:dataCorrupted(Swift.DecodingError.Context(codingPath:[],debugDescription:“给定的数据不是有效的JSON.”,underyingError:可选(error Domain=nscocaerorrordomain Code=3840“字符1周围的对象中没有字符串键。”UserInfo={NSDebugDescription=字符1周围的对象中没有字符串键。})))
我是否使用了Decodables错误?在解码数据时,我需要注意的唯一问题是设置日期解码策略。只需将DateDecoding策略设置为
.secondsSince1970
。试着这样做:
操场测试
struct Quote: Codable {
let language,region, quoteType, quoteSourceName: String
let triggerable: Bool
let currency: String
let firstTradeDateMilliseconds, priceHint: Int
let regularMarketChange, regularMarketChangePercent: Double
let regularMarketTime: Int
let regularMarketPrice, regularMarketDayHigh: Double
let regularMarketDayRange: String
let regularMarketDayLow: Double
let regularMarketVolume: Int
let regularMarketPreviousClose, bid, ask: Double
let bidSize, askSize: Int
let fullExchangeName, financialCurrency: String
let regularMarketOpen: Double
let averageDailyVolume3Month, averageDailyVolume10Day: Int
let fiftyTwoWeekLowChange, fiftyTwoWeekLowChangePercent: Double
let fiftyTwoWeekRange: String
let fiftyTwoWeekHighChange, fiftyTwoWeekHighChangePercent: Double
let fiftyTwoWeekLow, fiftyTwoWeekHigh: Double
let dividendDate, earningsTimestamp, earningsTimestampStart, earningsTimestampEnd: Date
let trailingAnnualDividendRate, trailingPE, trailingAnnualDividendYield, epsTrailingTwelveMonths, epsForward, epsCurrentYear, priceEpsCurrentYear: Double
let sharesOutstanding: Int
let bookValue, fiftyDayAverage, fiftyDayAverageChange, fiftyDayAverageChangePercent, twoHundredDayAverage, twoHundredDayAverageChange, twoHundredDayAverageChangePercent: Double
let marketCap: Int
let forwardPE, priceToBook: Double
let sourceInterval, exchangeDataDelayedBy: Int
let tradeable: Bool
let exchange, shortName, longName, marketState, messageBoardId, exchangeTimezoneName, exchangeTimezoneShortName: String
let gmtOffSetMilliseconds: Int
let market: String
let esgPopulated: Bool
let displayName, symbol: String
}
这会打印出来 根目录(optionChain:[uuuuLLDB\uExpr\u184.optionChain:[uuuLLDB\uExpr\u184.result:[uuuuLLDB\uExpr\u184.result:[uuUllDB\u184.result:[uUllDB\u184.result:[uUllDB\uExpr\u184.result:][55、60、65、70、75、80、85、90、95、96、97、98、99、100、101、102、103、104、105、106、107、108、109、110、111、112、113、114、115、116、131、132、133、155、160、165、170、175],具有迷你选项:false,引号:“美国”,区域:“美国”,引号etype:“股票”,引号“纳斯达克实时价格”,可触发:true,货币:“USD”,FirstTradeDate毫秒数:345479400000,价格提示:2,regularMarketChange:-2.2599945,regularMarketChangePercent:-1.9260223,regularMarketTime:160615268,regularMarketPrice:115.08,regularMarketDayHigh:117.62,regularMarketDayRange:“113.8-117.62”,regularMarketDayLow:113.8,regularMarketVolume:66403356,regularMarketPreviousClose:117.34,bid:114.79,ask:114.78,bidSize:9,askSize:10,fullExchangeName:“纳斯达克”,金融货币:“美元”,定期市场开放时间:117.18,平均日销量3个月:150914918,平均日销量10天:78477066,第五十二周周销量变化率:61.9275,第五十二周销量变化率:1.165091,第五十二周销量变化率:“53.1525-137.98”更新:2007-5-13阅读:第五周工资变动率:22.899994,第五周工资变动率:0.16596605,第五周工资变动率:53.1525,第五周工资变动率:137.98,除名日期:2020-11-12 00:00:00+0000,收入时间戳:2020-10-29 16:30:00+0000,收入时间戳开始时间:2021-01-26 10:59:00+0000,收入时间戳结束时间:2021-02-01 12:00:00+0000,跟踪年度工资:0.795,追踪PE:35.085365,追踪年度分割区:0.0067751836,追踪十二个月:3.28,追踪远期:4.33,追踪本年度:3.96,价格EPS本年度:29.060606,股票存续期:17102499840,账面价值:3.849,五日平均:116.774574,五日平均变化率:-1.6945724,五日平均变化率:-0.014511485,二百平均值:104.00763,百分之二百平均变化率:11.072372,百分之二百平均变化率:0.10645731,市值:1956567187456,转发器:26.577368,价格书籍:29.898676,源区间:15,交换地址延迟:0,可交易:假,交换:“NMS”,简称:“苹果公司”,长名:“苹果公司”,市场状态:“常规”,留言板ID:“finmb_24937”,exchangeTimezoneName:“美国/纽约”,exchangeTimezoneShortName:“EST”,GMTOFFSET:-18000000,market:“美国市场”,esgPopulated:false,displayName:“苹果”,symbol:“AAPL”),期权:[[uuuuuuLLDB_expr_184.期权(到期日期:2020-11-27 00:00:00+0000,最小期权:false(合同符号:“AAPL201127C00165000”,罢工:165,货币:“USD”,最新价格:0.01,变动:0.0,百分比变动:0.0,数量:可选(1),未平仓利息:156,出价:0.0,要求:0.01,合同金额:“常规”,到期日期:2020-11-27 00:00:00+0000,最新交易日期:2020-11-18 20:25:00+0000,隐含效用:1.000005,货币:假),lldb,expr,184.调用(合同符号:“AAPL201127C00170000”,罢工:170,货币:“USD”,最后价格:0.01,变动:0.0,百分比变动:0.0,数量:可选(11),未平仓利息:353,出价:0.0,要求:0.01,合同金额:常规,有效期:2020-11-27 00:00:00+0000,最后交易日期:2020-11-18 20:25:15+0000,隐含效用:1.0625046875000002,货币:假),lldb\u expr\u 184.呼叫(合同符号:“AAPL201127C00175000”,罢工:175,货币:“USD”,最后价格:0.01,变更:0.0,百分比变更:0.0,数量:可选(5),openInterest:259,出价:0.0,出价:0.01,合同规模:“常规”,有效期:2020-11
struct Root: Codable {
let optionChain: OptionChain
}
struct OptionChain: Codable {
let result: [Result]
}
struct Result: Codable {
let underlyingSymbol: String
let expirationDates: [Date]
let strikes: [Int]
let hasMiniOptions: Bool
let quote: Quote
let options: [Option]
}
struct Option: Codable {
let expirationDate: Date
let hasMiniOptions: Bool
let calls: [Call]
let puts: [Call]
}
struct Call: Codable {
let contractSymbol: String
let strike: Int
let currency: String
let lastPrice: Double
let change, percentChange: Double
let volume: Int?
let openInterest: Int
let bid, ask: Double
let contractSize: String
let expiration, lastTradeDate: Date
let impliedVolatility: Double
let inTheMoney: Bool
}
struct Quote: Codable {
let language,region, quoteType, quoteSourceName: String
let triggerable: Bool
let currency: String
let firstTradeDateMilliseconds, priceHint: Int
let regularMarketChange, regularMarketChangePercent: Double
let regularMarketTime: Int
let regularMarketPrice, regularMarketDayHigh: Double
let regularMarketDayRange: String
let regularMarketDayLow: Double
let regularMarketVolume: Int
let regularMarketPreviousClose, bid, ask: Double
let bidSize, askSize: Int
let fullExchangeName, financialCurrency: String
let regularMarketOpen: Double
let averageDailyVolume3Month, averageDailyVolume10Day: Int
let fiftyTwoWeekLowChange, fiftyTwoWeekLowChangePercent: Double
let fiftyTwoWeekRange: String
let fiftyTwoWeekHighChange, fiftyTwoWeekHighChangePercent: Double
let fiftyTwoWeekLow, fiftyTwoWeekHigh: Double
let dividendDate, earningsTimestamp, earningsTimestampStart, earningsTimestampEnd: Date
let trailingAnnualDividendRate, trailingPE, trailingAnnualDividendYield, epsTrailingTwelveMonths, epsForward, epsCurrentYear, priceEpsCurrentYear: Double
let sharesOutstanding: Int
let bookValue, fiftyDayAverage, fiftyDayAverageChange, fiftyDayAverageChangePercent, twoHundredDayAverage, twoHundredDayAverageChange, twoHundredDayAverageChangePercent: Double
let marketCap: Int
let forwardPE, priceToBook: Double
let sourceInterval, exchangeDataDelayedBy: Int
let tradeable: Bool
let exchange, shortName, longName, marketState, messageBoardId, exchangeTimezoneName, exchangeTimezoneShortName: String
let gmtOffSetMilliseconds: Int
let market: String
let esgPopulated: Bool
let displayName, symbol: String
}
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
let root = try decoder.decode(Root.self, from: .init(json.utf8))
print(root)
} catch {
print(error)
}