首页 > 解决方案 > 如何使用响应数据解码值

问题描述

投资组合模型

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?
    }
}

WebServicesClientServer

    .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 块错误消息

解码错误:keyNotFound(CodingKeys(stringValue: "stockValue", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "data", intValue: nil), _JSONKey(stringValue: "Index 0", intValue : 0)], debugDescription: "No value associated with key CodingKeys(stringValue: \"stockValue\", intValue: nil) (\"stockValue\").", underlyingError: nil))

我知道它的错误解码方式!所有所有字符串值都变成一个struct Portfolio但是我可以通过以下 ProtfolioModel 来实现它吗?

标签: jsonswiftdecoding

解决方案


注意:仍然需要验证这一点,但这是我处理 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
            }

推荐阅读