我需要解码以下格式的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个标题中的值,但这取决于用户选择确定的UserDefaults值。 IE,如果用户选择GBP作为他们的defaultCurrency,我只需要从结构货币中获取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)"
}
}
基本上这就是我所需要的,但它说:“枚举大小写的原始值必须是文字”
有什么建议吗?谢谢。
答案 0 :(得分:1)
您可以尝试
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]