swiftui - 使用奇怪的 JSON 文件格式查找汇率键值
问题描述
在给定密钥(3 位货币代码)的情况下,我需要有关货币汇率查找的帮助。JSON 对象非常不寻常,没有日期、时间戳、成功或速率等标签。第一个字符串值是基础货币或本国货币。在下面的示例中,它是“usd”(美元)。
我想通过给出其 3 位货币代码并将其存储在有序数组中来循环所有货币以获取每种汇率。
{
"usd": {
"aed": 4.420217,
"afn": 93.3213,
"all": 123.104693,
"amd": 628.026474,
"ang": 2.159569,
"aoa": 791.552347,
"ars": 111.887966,
"aud": 1.558363,
"awg": 2.164862,
"azn": 2.045728,
"bam": 1.9541,
"bbd": 2.429065,
"bch": 0.001278
}
}
在格式稍有不同的 JSON 对象中,我使用以下循环将汇率复制到有序数组。
for index in 0..<userData.rateArray.count {
currencyCode = currCode[index]
if let unwrapped = results.rates[currencyCode] {
userData.rateArray[index] = 1.0 / unwrapped
}
}
以下代码是用于获取 3 位货币代码和汇率的 API(通过 UpdateRates 调用)。
class GetCurrency: Codable {
let id = UUID()
var getCurrencies: [String : [String: Double]] = [:]
required public init(from decoder: Decoder) throws {
do{
print(#function)
let baseContainer = try decoder.singleValueContainer()
let base = try baseContainer.decode([String : [String: Double]].self)
for key in base.keys{
getCurrencies[key] = base[key]
}
}catch{
print(error)
throw error
}
}
}
class CurrencyViewModel: ObservableObject{
@Published var results: GetCurrency?
@Published var selectedBaseCurrency: String = "usd"
func UpdateRates() {
let baseUrl = "https://cdn.jsdelivr.net/gh/fawazahmed0/currency-api@1/latest/currencies/"
let baseCur = selectedBaseCurrency // usd, eur, cad, etc
let requestType = ".json"
guard let url = URL(string: baseUrl + baseCur + requestType) else {
print("Invalid URL")
return
}
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
do{
let decodedResponse = try JSONDecoder().decode(GetCurrency.self, from: data)
DispatchQueue.main.async {
self.results = decodedResponse
// this prints out the complete table of currency code and exchange rates
print(self.results?.getCurrencies["usd"] ?? 0.0)
}
} catch {
//Error thrown by a try
print(error)//much more informative than error?.localizedDescription
}
}
if error != nil {
//data task error
print(error!)
}
}.resume()
}
}
解决方案
感谢 lorem ipsum 的帮助。下面是更新的 ASI 逻辑,它使用键/值查找将汇率复制到 rateArray。
class CurrencyViewModel: ObservableObject{
@Published var results: GetCurrency?
@Published var rateArray = [Double] ()
init() {
if UserDefaults.standard.array(forKey: "rates") != nil {
rateArray = UserDefaults.standard.array(forKey: "rates") as! [Double]
}else {
rateArray = [Double] (repeating: 0.0, count: 160)
UserDefaults.standard.set(self.rateArray, forKey: "rates")
}
}
func updateRates(baseCur: String) {
...
DispatchQueue.main.async {
self.results = decodedResponse
// loop through all available currencies
for index in 0..<currCode.count {
currencyCode = currCode[index]
// spacial handling for base currency
if currencyCode == baseCur {
self.rateArray[index] = 1.0000
} else {
let homeRate = self.results?.getCurrencies[baseCur]
// complement and save the exchange rate
if let unwrapped = homeRate?[currencyCode] {
self.rateArray[index] = 1.0 / unwrapped
}
}
}
}
} catch {
//Error thrown by a try
print(error)//much more informative than error?.localizedDescription
}
}
if error != nil {
//data task error
print(error!)
}
}.resume()
}
}
推荐阅读
- quarkus - Quarkus 强化指南,如 CIS 或 STIG
- hashicorp-vault - 给定 Vault 中的路径,我如何找到可以访问它的人?
- reactjs - React - 用户登录和令牌验证
- html - 如何根据我从 a 中选择的值锁定 CSS 中的过渡
- c++ - 将未知结构传递给函数
- javascript - 尝试将数组的每个元素添加到下一个元素中未知数量的元素
- javascript - 在 React 中定义一个按钮(“取消”)来关闭整个反应应用程序而不是窗口?
- html - Chrome 中 :dir() 的替代方法是什么?
- tsql - 如何在 sp_executesql 语句的参数定义中连接字符串值?
- html - 使用 Bootstrap 5 时无法让空白消失