Как Декодируемое значение с данными ответа - PullRequest
0 голосов
/ 05 апреля 2019

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 (IndexValue: Index): ", intValue: 0)], debugDescription:" Нет значения, связанного с ключом CodingKeys (stringValue: \ "stockValue \", intValue: nil) (\ "stockValue \"). ", underError: nil))

Я знаю, что это неправильный способ декодирования! Все строковые значения в одном struct Portfolio Но можно ли добиться этого с помощью следующей модели ProtfolioModel?

Ответы [ 2 ]

0 голосов
/ 05 апреля 2019

ПРИМЕЧАНИЕ: Еще нужно проверить это, но это было мое решение для обработки JSON.

Была такая же проблема для декодирования JWT.

Шаги какзатем:

  1. Преобразование данных в UTF8
let data = response.data(using: .utf8)!
Сериализация объекта JSON
guard let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] else { return }
Используйте Struct для интерпретации данных (при необходимости измените)
        struct Json {
            let data: Array?

            init(json: [String: Any]) {
                data = json["data"] as? Array ?? []
            }
        }
Получить данные в виде ключа объекта
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
            }
0 голосов
/ 05 апреля 2019

Ошибка довольно очевидна: в массиве нет ключа 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"
    }
}
...