如何解析具有字典 key:value 对的 json 数据?我正在尝试提取符号和值对

How parse a json data that has a dictionary key:value pair? I'm trying to extract the symbol and value pair

如何正确解析以下json数据? 我的问题在行:if let rates = data["rates"] as? NSDictionary...

json数据

{   "valid": true,   
    "timestamp": 1579683079,   
    "base": "USD",  
    "rates": {
       "AED": 3.67316,
       "AFN": 77.99911,
       "ALL": 110.11741,
       ...
       "ZAR": 14.45,
       "ZMW": 14.63257   
     } 
 }

代码

import UIKit

struct CurrencyRate {
    var valid: String
    var timestamp: Int
    var base: String
    var rates: [String:Double] = [:]
}

class ViewController: UIViewController {

var mySymbols:[String] = []
var myValues:[Double] = []


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.

    let jsonUrlString = "https://currencyapi.net/api/v1/rates?key=6b171cc58787d922eb53e3684d97784d165a&base=USD"

    guard let url = URL(string: jsonUrlString) else { return }

    URLSession.shared.dataTask(with: url) { (data, response, err) in
        guard let data = data else { return }

        //let dataAsString = String(data: data, encoding: .utf8)
        if let rates = data["rates"] as? NSDictionary {
            for (key, value) in rates {
                self.mySymbols.append((key as? String)!)

                self.myValues.append((value as? Double)!)
            }
        }


    }.resume()

}

}

不要使用 NSDictionary - 使用 Dictionary 输入 Swift。此外,您有 data 并且它根本不是字典。是 Data 类型。使用应该将您的数据转换为您的类型。尝试使用此代码:

URLSession.shared.dataTask(with: url) { (data, response, err) in
    guard let data = data else { return }

    let jsonResult = try? JSONSerialization.jsonObject(with: data)

    if let dict = jsonResult as? Dictionary<String, Any>, let rates = dict["rates"] as? Dictionary<String, Double> {
        for (key, value) in rates {
            print(key, value)
            self.mySymbols.append(key)
            self.myValues.append(value)
        }
    }
}.resume()

Codable 有一个方法,但我想这将是您的下一个挑战。另外,请记住,代码是异步执行的,全局变量中的数据不会立即出现

语法

for (key, value) in ...

枚举字典只存在于本机 Swift 字典中。

这应该是可行的,如果您强制转换为特定的 [String:Double],您甚至可以摆脱 keyvalue.

的丑陋类型转换
if let rates = data["rates"] as? [String:Double] {
    for (key, value) in rates {
        self.mySymbols.append(key)
        self.myValues.append(value)
    }
}

但是我们鼓励您使用 Decodable 协议来解析 JSON。只有一些细微的变化。

struct CurrencyRate : Decodable {
    let valid: Bool // must be Bool
    let timestamp: Date 
    let base: String
    let rates: [String:Double]
}

var rates = [String:Double]()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.

    let jsonUrlString = "https://currencyapi.net/api/v1/rates?key=6b171cc58787d922eb53e3684d97784d165a&base=USD"

    guard let url = URL(string: jsonUrlString) else { return }

    URLSession.shared.dataTask(with: url) { (data, _, error) in
        guard let error = error else { print(error); return }

        do {
           let decoder = JSONDecoder()
           decoder.dateDecodingStrategy = .secondsSince1970
           let result = try decoder.decode(CurrencyRate.self, from: data!)
           self.rates = result.rates
           print(rates)
        } catch {
            print(error)
        }
    }.resume()   
}

timestamp 被解码为 Date