如何使用响应数据解码值

问题描述 投票:0回答:2

投资模型

public struct PortfolioModel : Decodable {

    let symbols_requested: Int
    let symbols_returned: Int
    let data: [Portfolio]
}
struct Portfolio : Decodable {

    let stockValue : StockValue
    let todaysLowHigh : HighLowValue
    let fiftyTwoWeekLowHigh : HighLowValue
    let priceBandLowHigh : HighLowValue
    let stockPriceValue : StockPriceValue
    let stockStatistics : StockStatistics

    struct StockValue: Decodable {

        let stockName: String?
        let stockCurrentPrice: String?
        let stockChangeValue : String?
        let stockVolume : String?
        let stockDateValue : String?
    }

    struct HighLowValue: Decodable {

        let minimumValue : String?
        let maximumValue : String?
        let currentValue : String?
    }

    struct StockPriceValue: Decodable {

        let bidPriceValue : String?
        let bidQtyValue : String?
        let offerPriceValue : String?
        let offerOtyValue : String?
        let openPriceValue : String?
    }

    struct  StockStatistics : Decodable{

        let stockMarketCapValue : String?
        let stockDividendValue : String?
        let stockDivYield : String?
        let stockfaceValue :String?
        let stockMarketLot : String?
        let stockIndustryPE : String?

        let stockEPSTTM  : StandColidate
        let stockPC : StandColidate
        let stockPE : StandColidate
        let stockPriceBook : StandColidate
        let stockBookValue : StandColidate

        let stockDeliverables : String?
    }

    struct StandColidate : Decodable{

        let standalone : String?
        let consolidate: String?
    }
}

Web客户端服务器

    .responseJSON { response in
        switch response.result {
        case .success:
            let decoder = JSONDecoder()
            decoder.dateDecodingStrategy = .iso8601
            do {

                let result = try decoder.decode(PortfolioModel.self, from: response.data!)
                self.portfolio = result.data
                print(result.data)
                completion(self.portfolio)

                return
            }
                catch {
                    MKProgress.hide()
                    print("Decoding error:", error)
                }
            case .failure(let error):
                MKProgress.hide()
                print("Request failed with error: \(error)")
            }

服务器响应

{
    "symbols_requested": 1,
    "symbols_returned": 1,
    "data": [
        {
            "symbol": "AAPL",
            "name": "Apple Inc.",
            "currency": "USD",
            "price": "196.85",
            "price_open": "196.45",
            "day_high": "197.10",
            "day_low": "195.93",
            "52_week_high": "233.47",
            "52_week_low": "142.00",
            "day_change": "1.16",
            "change_pct": "0.59",
            "close_yesterday": "195.69",
            "market_cap": "926316741610",
            "volume": "8909408",
            "volume_avg": "28596757",
            "shares": "4715280000",
            "stock_exchange_long": "NASDAQ Stock Exchange",
            "stock_exchange_short": "NASDAQ",
            "timezone": "EDT",
            "timezone_name": "America/New_York",
            "gmt_offset": "-14400",
            "last_trade_time": "2019-04-05 12:28:19"
        }
    ]
}

我收到了catch block错误消息

解码错误:keyNotFound(CodingKeys(stringValue:“stockValue”,intValue:nil),Swift.DecodingError.Context(codingPath:[CodingKeys(stringValue:“data”,intValue:nil),_ JSONKey(stringValue:“Index 0”,intValue :0)],debugDescription:“没有与键CodingKeys相关的值(stringValue:\”stockValue \“,intValue:nil)(\”stockValue \“)。”,underlyingError:nil))

我知道它错误的解码方式!将所有String值都转换为单个struct Portfolio但是我可以使用以下ProtfolioModel实现它吗?

json swift decoding
2个回答
0
投票

错误很明显:关键stockValue数组中没有关键的data。无论如何,没有字典表示该数组中的结构。

这两个结构匹配JSON,在quicktype.io上快速创建

public struct PortfolioModel : Decodable {

    let symbolsRequested: Int
    let symbolsReturned: Int
    let data: [Portfolio]

    enum CodingKeys: String, CodingKey {
        case symbolsRequested = "symbols_requested"
        case symbolsReturned = "symbols_returned"
        case data = "data"
    }
}

struct Portfolio: Codable {
    let symbol, name, currency, price, priceOpen, dayHigh, dayLow: String
    let the52_WeekHigh, the52_WeekLow, dayChange, changePct, closeYesterday, marketCap: String
    let volume, volumeAvg, shares, stockExchangeLong, stockExchangeShort, timezone: String
    let timezoneName, gmtOffset, lastTradeTime: String

    enum CodingKeys: String, CodingKey {
        case symbol = "symbol", name = "name", currency = "currency"
        case price = "price", priceOpen = "price_open", dayHigh = "day_high"
        case dayLow = "day_low", the52_WeekHigh = "52_week_high", the52_WeekLow = "52_week_low"
        case dayChange = "day_change", changePct = "change_pct", closeYesterday = "close_yesterday"
        case marketCap = "market_cap", volume = "volume", volumeAvg = "volume_avg", shares = "shares"
        case stockExchangeLong = "stock_exchange_long", stockExchangeShort = "stock_exchange_short"
        case timezone = "timezone", timezoneName = "timezone_name", gmtOffset = "gmt_offset", lastTradeTime = "last_trade_time"
    }
}

0
投票

注意:仍然需要验证这一点,但这是我处理JSON的解决方案。

有同样的问题解码JWT。

步骤如下:

  1. 将数据转换为UTF8
let data = response.data(using: .utf8)!
  1. 序列化JSON对象
guard let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] else { return }
  1. 使用Struct来解释数据(根据需要进行修改)
        struct Json {
            let data: Array?

            init(json: [String: Any]) {
                data = json["data"] as? Array ?? []
            }
        }
  1. 获取数据作为对象键
let dataArray = Json(json: json)
let symbol = dataArray.data.symbol ?? ""

全部一起:

            do {
                let data = response.data(using: .utf8)!
                guard let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] else { return }
                let dataArray = Json(json: json)
                let symbol = dataArray.data.symbol ?? ""
            } catch {
                let message = "Failed to extract token from json object"
                // Your error message handle
                // logMessage(messageText: message)
                return
            }
© www.soinside.com 2019 - 2024. All rights reserved.