如何使用带有可变键的可编码解码 JSON?



>我需要解码一个格式如下的JSON:

{
"rates": {
"btc": {
"name": "Bitcoin",
"unit": "Ƀ",
"value": 0,
"type": "crypto"
},
"eth": {
"name": "Ether",
"unit": "Ξ",
"value": 29.658,
"type": "crypto"
},
"bch": {
"name": "Bitcoin Cash",
"unit": "BCH",
"value": 12.3,
"type": "crypto"
},
"ltc": {
"name": "Litecoin",
"unit": "Ł",
"value": 108.219,
"type": "crypto"
}...}

我目前得到的数据是这样的,我不满意:

import Foundation
class CGExchange {
static let shared = CGExchange()
var defaultCurrency = UserDefaults.standard.value(forKey: "DefaultCurrency")!
struct Rates: Codable {
let rates: Currency
}
struct Exchange: Codable {
let name: String
let value: Double
let unit: String
}
struct Currency: Codable {
let btc: Exchange
let eth: Exchange
let bch: Exchange
let ltc: Exchange
let usd: Exchange
let aed: Exchange
let ars: Exchange
let aud: Exchange
let bdt: Exchange
let bhd: Exchange
let bmd: Exchange
let brl: Exchange
let cad: Exchange
let chf: Exchange
let clp: Exchange
let cny: Exchange
let czk: Exchange
let dkk: Exchange
let eur: Exchange
let gbp: Exchange
let hkd: Exchange
let huf: Exchange
let idr: Exchange
let ils: Exchange
let inr: Exchange
let jpy: Exchange
let krw: Exchange
let kwd: Exchange
let lkr: Exchange
let mmk: Exchange
let mxn: Exchange
let myr: Exchange
let nok: Exchange
let nzd: Exchange
let php: Exchange
let pkr: Exchange
let pln: Exchange
let rub: Exchange
let sar: Exchange
let sek: Exchange
let sgd: Exchange
let thb: Exchange
let `try`: Exchange
let twd: Exchange
let vef: Exchange
let zar: Exchange
let xdr: Exchange
let xag: Exchange
let xau: Exchange
}
var exchangeData = [Rates]()
func getData(arr: Bool, completion: @escaping (Bool) -> ()) {
/// alamofire / urlsession request
let urlJSON = "https://api.coingecko.com/api/v3/exchange_rates"
guard let url = URL(string: urlJSON) else { return }
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else { return }
do {
//                let currencies = try JSONDecoder().decode(Currency.self, from: data)
let exchanges = try JSONDecoder().decode(Rates.self, from: data)
self.exchangeData = [exchanges]
print(self.exchangeData)
completion(arr)
} catch let jsonErr {
print("error serializing json: (jsonErr)")
}
}.resume()
}
func refresh(completion: () -> ()) {
defaultCurrency = UserDefaults.standard.string(forKey: "DefaultCurrency")!
completion()
}
}

问题是我只需要"费率"中保存的 3 个标题的值,但这取决于用户选择确定的用户默认值值。IE,如果用户选择 GBP 作为他们的默认货币,我只需要从结构货币中获取 let gbp,但获取值很尴尬,因为我无法更改它。即在我的 DataViewController 中获取我所做的数据let exchangeRate = CGExchange.shared.exchangeData[0].rates.gbp.value但理想情况下,我需要根据默认货币更改结构。即let exchangeRate = CGExchange.shared.exchangeData[0].rates.defaultCurrency.value

但我正在努力找出我将如何做到这一点。 如果我可以用可以更改的值创建一个结构,例如:

struct Currency: Codable {
let dc: Exchange
let sc: Exchange
let tc: Exchange
enum CodingKeys: String, CodingKey {
case dc = "(defaultCurrency)"
case sc = "(secondCurrency)"
case tc = "(currency)"
}
}

这基本上是我需要的,但它说:"枚举大小写的原始值必须是文字">

有什么建议吗?谢谢。

你可以试试

struct Rates: Codable {
let rates: [String:Exchange]
}
struct Exchange: Codable {
let name: String
let value: Double
let unit: String 
}

然后使用

let defCurrency = <#setHere#> // "btc"
let ex =  CGExchange.shared.exchangeData[0].rates[defCurrency]

相关内容

  • 没有找到相关文章

最新更新