【问题标题】:How do I correctly format my structures to the API I am using?如何将我的结构正确格式化为我正在使用的 API?
【发布时间】:2020-03-01 17:58:16
【问题描述】:

我正在使用 Aplhadvantage API。它的结构是:

{
    "Global Quote": {
        "01. symbol": "MSFT",
        "02. open": "152.4100",
        "03. high": "163.7100",
        "04. low": "152.0000",
        "05. price": "162.0100",
        "06. volume": "96388312",
        "07. latest trading day": "2020-02-28",
        "08. previous close": "158.1800",
        "09. change": "3.8300",
        "10. change percent": "2.4213%"
    }
}

我已经创建了我的结构:

import Foundation

struct StockResponse: Decodable{
    var response: Stocks
}

struct Stocks: Decodable{
    var stocks: [StockInfo]
}

struct StockInfo: Decodable{
    var open: String
    var high: String
    var low: String
    var close: String
    var volume: String
}

我的解码器是:

    func getStock (completion: @escaping(Result<[StockInfo], StockError>) -> Void) {
        let dataTask = URLSession.shared.dataTask(with: resourceURL) { data, _,_ in
            guard let jsonData = data else{
                completion(.failure(.noDataAvailable))
                return
            }
            do{
                let decoder = JSONDecoder()
                let stocksResponse = try decoder.decode(StockResponse.self, from: jsonData)
                let stockDetails = stocksResponse.response.stocks
                completion(.success(stockDetails))
            }
            catch{
                completion(.failure(.canNotProcessData))
            }
        }
        dataTask.resume()
    }

每次运行代码时,都会收到 canNotProcessData 错误。所以程序成功获取数据,但无法处理。我将如何解决这个问题?

【问题讨论】:

  • 打印 catch 块中的错误。它准确地告诉你哪里出了问题。像通用 canNotProcessData 这样的东西是毫无意义的。

标签: json swift api stock


【解决方案1】:

您可以使用QuickType 将您的数据转换为标准的 swift 模型。您的结构键与您的响应不同。

应该是这样的:

// MARK: - DataClass
struct DataClass: Codable {
    let globalQuote: GlobalQuote

    enum CodingKeys: String, CodingKey {
        case globalQuote = "Global Quote"
    }
}

// MARK: - GlobalQuote
struct GlobalQuote: Codable {
    let the01Symbol, the02Open, the03High, the04Low: String
    let the05Price, the06Volume, the07LatestTradingDay, the08PreviousClose: String
    let the09Change, the10ChangePercent: String

    enum CodingKeys: String, CodingKey {
        case the01Symbol = "01. symbol"
        case the02Open = "02. open"
        case the03High = "03. high"
        case the04Low = "04. low"
        case the05Price = "05. price"
        case the06Volume = "06. volume"
        case the07LatestTradingDay = "07. latest trading day"
        case the08PreviousClose = "08. previous close"
        case the09Change = "09. change"
        case the10ChangePercent = "10. change percent"
    }
}

【讨论】:

  • 根据我的结构,您应该将此行 let stocksResponse = try decoder.decode(StockResponse.self, from: jsonData) 更改为:let stocksResponse = try decoder.decode(DataClass.self, from: jsonData)
  • 我应该如何初始化globalQuote? let stockDetails = DataClass.init(globalQuote: )
  • 你可以访问像let stockDetails = DataClass. globalQuote这样的值
  • 如果我这样做,我会收到错误Instance member 'globalQuote' cannot be used on type 'DataClass'
  • 我的代码是let stockDetails = DataClass.globalQuote
猜你喜欢
  • 2014-01-07
  • 2021-08-30
  • 2015-08-25
  • 1970-01-01
  • 2018-02-18
  • 2019-11-13
  • 1970-01-01
  • 1970-01-01
  • 2016-07-23
相关资源
最近更新 更多