【发布时间】:2020-11-14 14:30:33
【问题描述】:
我一直在努力解决这个问题!我有 Alamofire 和 SwiftyJSON。我使用 Alamofire 从 Yahoo Finance 获取 JSON 结果,如下所示:
public func getYahooQuote(symbol: String) {
let stockURL = "https://query1.finance.yahoo.com/v7/finance/quote?symbols=" + symbol
let request = AF.request(stockURL, parameters: ["quoteResponse": "result"])
request.responseData { (response) in
guard let data = response.value else {return}
do {
let json = try JSON(data: data)
print(json)
let decoder = JSONDecoder()
let stock = try decoder.decode(QuoteParent.self, from: data)
print(stock)
} catch {
print(error)
}
}
}
因此,该请求需要一个字符串变量符号,该符号将传递给函数。我得到的结果是一个打印这个的 JSON 对象: '
{
"quoteResponse" : {
"result" : [
{
"fiftyTwoWeekLow" : 164.93000000000001,
"regularMarketVolume" : 33445281,
"messageBoardId" : "finmb_8108558",
"symbol" : "QQQ",
"currency" : "USD",
"regularMarketPreviousClose" : 258.00999999999999,
"fiftyDayAverage" : 250.32285999999999,
"exchange" : "NMS",
"quoteType" : "ETF",
"regularMarketDayLow" : 251.31999999999999,
"averageDailyVolume10Day" : 46768962,
"fiftyTwoWeekHighChange" : -15.310013,
"priceHint" : 2,
"twoHundredDayAverageChange" : 31.669998,
"exchangeTimezoneName" : "America\/New_York",
"bookValue" : 188.77500000000001,
"firstTradeDateMilliseconds" : 921076200000,
"averageDailyVolume3Month" : 42292663,
"tradeable" : false,
"bidSize" : 8,
"sourceInterval" : 15,
"regularMarketChange" : -3.530014,
"triggerable" : true,
"longName" : "Invesco QQQ Trust",
"market" : "us_market",
"exchangeTimezoneShortName" : "EDT",
"regularMarketDayHigh" : 256.93000000000001,
"marketCap" : 100036083712,
"gmtOffSetMilliseconds" : -14400000,
"fiftyTwoWeekHighChangePercent" : -0.056747886999999997,
"askSize" : 10,
"language" : "en-US",
"marketState" : "REGULAR",
"fiftyTwoWeekRange" : "164.93 - 269.79",
"twoHundredDayAverage" : 222.81,
"trailingAnnualDividendRate" : 1.54,
"quoteSourceName" : "Delayed Quote",
"trailingThreeMonthReturns" : 30.27,
"fiftyDayAverageChange" : 4.1571350000000002,
"shortName" : "Invesco QQQ Trust, Series 1",
"fiftyDayAverageChangePercent" : 0.016607093,
"region" : "US",
"regularMarketTime" : 1595609084,
"priceToBook" : 1.3480599,
"regularMarketOpen" : 254.12,
"fiftyTwoWeekLowChange" : 89.549999999999997,
"regularMarketDayRange" : "251.32 - 256.93",
"trailingAnnualDividendYield" : 0.0059687606999999998,
"fullExchangeName" : "NasdaqGS",
"regularMarketChangePercent" : -1.3681694,
"trailingPE" : 65.335044999999994,
"fiftyTwoWeekHigh" : 269.79000000000002,
"bid" : 254.56,
"epsTrailingTwelveMonths" : 3.895,
"trailingThreeMonthNavReturns" : 30.210000000000001,
"fiftyTwoWeekLowChangePercent" : 0.54295766000000001,
"twoHundredDayAverageChangePercent" : 0.14213903,
"ask" : 254.61000000000001,
"esgPopulated" : false,
"regularMarketPrice" : 254.47999999999999,
"sharesOutstanding" : 393100000,
"financialCurrency" : "USD",
"exchangeDataDelayedBy" : 0,
"ytdReturn" : 16.809999999999999
}
],
"error" : null
}
}
我有这样的 Codable 结构:
struct QuoteParent: Codable {
var quoteResponse: QuoteResponse
}
struct QuoteResponse: Codable {
var error: QuoteError?
var result: Stock?
}
struct QuoteError: Codable {
var lang: String?
var description: String?
var message: String?
var code: Int
}
struct Stock: Codable {
var ask : Decimal
var askSize : Int
var averageDailyVolume10Day : Int
var averageDailyVolume3Month : Int
var bid : Double
var bidSize : Int
var bookValue : Decimal
var currency : String
var epsTrailingTwelveMonths : Decimal
var esgPopulated : Bool
var exchange : String
var exchangeDataDelayedBy : Int
var exchangeTimezoneName : String
var exchangeTimezoneShortName : String
var fiftyDayAverage : Decimal
var fiftyDayAverageChange : Decimal
var fiftyDayAverageChangePercent : Decimal
var fiftyTwoWeekHigh : Decimal
var fiftyTwoWeekHighChange : Decimal
var fiftyTwoWeekHighChangePercent : Decimal
var fiftyTwoWeekLow : Decimal
var fiftyTwoWeekLowChange : Decimal
var fiftyTwoWeekLowChangePercent : Decimal
var fiftyTwoWeekRange : String?
var financialCurrency : String
var firstTradeDateMilliseconds : Int
var fullExchangeName : String
var gmtOffSetMilliseconds : Int
var language : String
var longName : String
var market : String
var marketCap : Int
var marketState : String
var messageBoardId : String
var priceHint : Int
var priceToBook : Decimal
var quoteSourceName : String
var quoteType : String
var region : String
var regularMarketChange : Int
var regularMarketChangePercent : Decimal
var regularMarketDayHigh : Decimal
var regularMarketDayLow : Decimal
var regularMarketDayRange : String
var regularMarketOpen : Double
var regularMarketPreviousClose : Decimal
var regularMarketPrice : Decimal
var regularMarketTime : Int
var regularMarketVolume : Int
var sharesOutstanding : Int
var shortName : String
var sourceInterval : Int
var symbol : String
var tradeable : Bool
var trailingAnnualDividendRate : Double
var trailingAnnualDividendYield : Decimal
var trailingPE : Decimal
var trailingThreeMonthNavReturns : Decimal
var trailingThreeMonthReturns : Decimal
var triggerable : Bool
var twoHundredDayAverage : Double
var twoHundredDayAverageChange : Decimal
var twoHundredDayAverageChangePercent : Decimal
var ytdReturn : Decimal
}
我尝试使用 JSONDecoder 对其进行解码,但这似乎需要一个 Data 对象,而我得到的对象是 JSON。
我使用这一行将 JSON 对象缩小为 result 的值,如下所示:
let json2 = json["quoteResponse"]["result"]
现在这仍然只是一个 JSON 对象,它确实包含我想要的所有数据,但我无法弄清楚如何将该 JSON 对象解析为我拥有的 Struct 类。这里的任何智慧都将不胜感激!
我确实尝试过这个来获取 JSON:
request.responseData { (response) in
而不是
request.responseJSON { (response) in
并尝试使用以下代码对其进行解码:
let decoder = JSONDecoder()
let stock = try decoder.decode(Stock.self, from: data)
但现在我得到这样的错误打印:
typeMismatch(Swift.Dictionary
【问题讨论】:
-
请注意所有数字类型都是错误的。只有双引号中的数字是
String,浮点值是Double,其他是Int、true和false(不是双引号)是Bool。而且Codable比SwiftyJSON要好得多。声明所有非可选内容,阅读您遇到的全面错误并解决问题。 -
谢谢!很好地抓住了 stuct 属性,我会改变那些。完成后,如何解码 JSON 对象?我尝试过使用 JSONDecoder(),但这似乎需要一个 Data 对象,而不是 JSON 对象。
-
用
.responseData替换.responseJSON -
谢谢,我这样做了,我得到的错误是:数据无法读取,因为它丢失了。
-
好吧,
print(error)在catch块中,而不是其他任何东西。它告诉你出了什么问题。提示:缺少根对象(带有quoteResponse键)。
标签: json swift alamofire swifty-json