【问题标题】:Iterating through dictionary keys of decoded JSON in Swift在 Swift 中遍历解码 JSON 的字典键
【发布时间】:2018-11-02 09:36:12
【问题描述】:

在上一个关于如何设置我的基础 JSON 模型的问题中,我得到了很好的帮助。我能够解析任何我想要的值。

虽然我可以解析任何我想要的值,但我只能使用点表示法分别访问符号或其他值。
btcSymbol = rawResponse.btc?.symbol
ethSymbol = rawResponse.eth?.symbol

我发现了其他关于迭代字典的问题,例如 Iterating Through a Dictionary in Swift,但这些示例是基本数组,而不是使用 Swift 新协议的多嵌套字典。

我希望能够:
1. 遍历 JSON 并从 CMC API 中仅提取符号
2. 有一个模型,我可以分别迭代每种货币的所有值,以便稍后将这些值发送到表格视图。
BTC | name | symbol | marketCap | MaxSupply
ETH | name | symbol | marketCap | MaxSupply

重组我现有的模型会是最佳解决方案吗?建立模型后,循环或地图的标准会更好吗?

JSON模型

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

【问题讨论】:

    标签: json swift


    【解决方案1】:

    至少我建议映射 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) }
    

    【讨论】:

      猜你喜欢
      • 2014-07-29
      • 1970-01-01
      • 2014-05-15
      • 1970-01-01
      • 1970-01-01
      • 2014-07-31
      • 2021-11-23
      • 1970-01-01
      • 2019-08-19
      相关资源
      最近更新 更多