在Swift中迭代解码JSON的字典键

在Swift中迭代解码JSON的字典键,json,swift,Json,Swift,在上一个问题中,我得到了非常好的帮助,关于如何建立我的基础JSON模型。我可以解析任何我想要的值 虽然我可以解析我想要的任何值,但我只能使用点符号分别访问符号或其他值。 btcSymbol=rawResponse.btc?.symbol ethSymbol=rawResponse.eth?.symbol 我还发现了关于迭代字典的其他问题,例如,但这些示例是基本数组,而不是使用Swift新协议的多嵌套字典 我希望能够: 1.迭代JSON并从CMC API中仅提取符号。 2.有一个模型,我可以分别迭

在上一个问题中,我得到了非常好的帮助,关于如何建立我的基础JSON模型。我可以解析任何我想要的值

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

ethSymbol=rawResponse.eth?.symbol

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

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

ETH | name | symbol | marketCap | MaxSupply

重组我已经存在的模型是最好的解决方案吗?在我的模型建立之后,在循环或映射中使用标准会更好吗

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


至少我建议映射
数据
字典,以获取
符号
作为键,而不是
id
,顺便说一句,如果键是可计算的,并且您通过
。例如,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) }
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) }