如何使用响应数据分解值

时间:2019-04-05 17:22:31

标签: json swift decoding

PortfolioModel

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:“与键CodingKeys(stringValue:\“ stockValue \”,intValue:nil)(\“ stockValue \”)。

我知道其解码方式错误!所有所有String值都合并为单个struct Portfolio,但是我可以使用ProtfolioModel来实现吗?

2 个答案:

答案 0 :(得分:0)

错误非常明显:数组Option Explicit 'download selenium https://github.com/florentbr/SeleniumBasic/releases/tag/v2.0.9.0 'Ensure latest applicable driver e.g. ChromeDriver.exe in Selenium folder 'VBE > Tools > References > Add reference to selenium type library Public Sub DownloadFile() Dim d As WebDriver, jsonText As String Set d = New ChromeDriver Const URL = "https://bet.hkjc.com/football/getJSON.aspx?jsontype=odds_allodds.aspx&matchid=default" With d .Start "Chrome" .get URL jsonText = .FindElementByCss("pre").Text Debug.Print jsonText Stop .Quit End With End Sub 中没有键stockValue。无论如何,在该数组中都没有表示结构的字典。

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

data

答案 1 :(得分: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
            }