Итерация по словарным ключам декодированного JSON в Swift - PullRequest
0 голосов
/ 23 мая 2018

Я получил отличную помощь в своем предыдущем вопросе о том, как настроить основную модель JSON.Я могу анализировать любые значения, которые хочу.

Хотя я могу анализировать любые значения, которые я хочу, я могу получить доступ только к символам или другим значениям отдельно, используя точечную запись.
btcSymbol = rawResponse.btc?.symbol
ethSymbol = rawResponse.eth?.symbol

Я нашел другие вопросы об итерации по словарям, например Итерация по словарю в Swift , но эти примеры - это базовые массивы, а не многоплановые словари, использующие новые протоколы Swift.

Я хочу иметь возможность:
1. Выполнить итерацию по JSON и извлечь только символы из CMC API.
2. Есть модель, в которой я могуитерировать все значения каждой валюты по отдельности, чтобы впоследствии я мог отправить эти значения, например, в табличное представление.
BTC | name | symbol | marketCap | MaxSupply
ETH | name | symbol | marketCap | MaxSupply

Лучше всего будет реструктурировать мою уже существующую модельрешение?После того, как моя модель построена, будет ли лучше стандарт для in loop или map?

JSONModel

struct RawServerResponse : Codable {
enum Keys : String, CodingKey {
    case data = "data"
}
let data : [String:Base]
}

struct Base : Codable {
enum CodingKeys : String, CodingKey {
    case id = "id"
    case name = "name"
    case symbol = "symbol"
}

let id : Int64
let name : String
let symbol : String
}

struct Quote : Codable {
enum CodingKeys : String, CodingKey {
    case price = "price"
    case marketCap = "market_cap"
}

let price :  Double
let marketCap : Double
}

extension RawServerResponse {
enum BaseKeys : String {
    case btc = "1"
    case eth = "1027"      
}
var btc : Base? { return data[BaseKeys.btc.rawValue] }
var eth : Base? { return data[BaseKeys.eth.rawValue] }

}

extension Base {
enum Currencies : String {
    case usd = "USD"
}
var usd : Quote? { return quotes[Currencies.usd.rawValue]}
}

struct ServerResponse: Codable {
let btcName: String?
let btcSymbol: String?

init(from decoder: Decoder) throws {
    let rawResponse = try RawServerResponse(from: decoder)

    btcSymbol = rawResponse.btc?.symbol

JSON

{
"data": {
    "1": {
        "id": 1, 
        "name": "Bitcoin", 
        "symbol": "BTC", 
        "website_slug": "bitcoin", 
        "rank": 1, 
        "circulating_supply": 17041575.0, 
        "total_supply": 17041575.0, 
        "max_supply": 21000000.0, 
        "quotes": {
            "USD": {
                "price": 8214.7, 
                "volume_24h": 5473430000.0, 
                "market_cap": 139991426153.0, 
                "percent_change_1h": 0.09, 
                "percent_change_24h": 2.29, 
                "percent_change_7d": -2.44
            }
        }
    }

1 Ответ

0 голосов
/ 23 мая 2018

По крайней мере, я бы рекомендовал сопоставить словарь data, чтобы получить symbol в качестве ключа, а не id, кстати, если ключи camelCaseable и вы передаете .convertFromSnakeCase стратегия декодирования ключей вам не нужны никакие ключи кодирования, например

struct RawServerResponse : Codable {
    var data = [String:Base]()

    private enum CodingKeys: String, CodingKey { case data }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let baseDictionary = try container.decode([String:Base].self, forKey: .data)
        baseDictionary.forEach { data[$0.1.symbol] = $0.1 }
    }
}

struct Base : Codable {
    let id : Int64
    let name : String
    let symbol : String
    let quotes : [String:Quote]
}

struct Quote : Codable {
    let price : Double
    let marketCap : Double
}

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let rawResponse = try decoder.decode(RawServerResponse.self, from: data)
    for (symbol, base) in rawResponse.data {
        print(symbol, base.quotes["USD"]?.marketCap)
        // ETH Optional(68660795252.0)
        // BTC Optional(139991426153.0)
    }
} catch { print(error) }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...