如何从 JSON 对象 Swift 中检索值 4

How to retrieve a value from JSON Object Swift 4

我正在尝试使用 Codable 和 Swift 4:

解码 JSON 对象
{
USD: {
"15m": 9977.49,
last: 9977.49,
buy: 9979.36,
sell: 9975.62,
symbol: "$"
    },
AUD: {
"15m": 13181.69,
last: 13181.69,
buy: 13184.16,
sell: 13179.22,
symbol: "$"
    },
TBD: {
"15m": 13181.69,
last: 13181.69,
buy: 13184.16,
sell: 13179.22,
symbol: "$"
    }
}

这是我到目前为止对对象模型所做的:

struct Currency: Codable {

    let fifteenMin: Double?
    let last: Double?
    let buy: Double
    let sell: Double
    let symbol: String

    enum CodingKeys: String, CodingKey {
        case fifteenMin = "15m"
        case last
        case buy
        case sell
        case symbol
    }
}

这就是我解码的方式:

var currencyName = [String]()
var currenciesArray = [Currency]()


func fetchCurrencyData() {
    guard let urlString = API.RateURL.absoluteString else { return }
    guard let url = URL(string: urlString) else { return }
    let jsonData = try! Data(contentsOf: url)
    let decoder = JSONDecoder()
    do {
        let currenciesData = try decoder.decode([String: Currency].self, from: jsonData)
        for currency in currenciesData {
            self.currencyName.append(currency.key)
            self.currenciesArray.append(currency.value)
        }
    } catch let err {
        print(err.localizedDescription)
    }
}

因此,当我想用​​该数据填充 tableView 中的行时,我使用 "for loop" 并在一个数组中追加 "USD"、"AUD" 等,在另一个数组中追加 Currency 对象。

获取数据和填充货币对象的更好方法是什么。因为我很确定将 JSON 的相同对象提取并附加到两个单独的数组中并不是我认为的好习惯。

如果我的问题不清楚,我可以更详细地解释我想要实现的目标。

谢谢。

货币名称不应该在 Currency 对象中吗?那将更容易操纵。

但是如果您必须使用那种格式,您可以创建一个元组数组或字典数组。

var currenciesArray = [(String, Currency)]() 

然后像这样追加:

for currency in currenciesData {
    currenciesArray.append((currency.key, currency.value))
}

p.s。 : JSON内的字符串值需要加引号("),否则无效。

****已添加*****

下面的代码将对 JSON 与您提到的代码类似的代码进行编码和解码:

struct Price: Codable {

    let fifteenMin: Double?
    let last: Double?
    let buy: Double
    let sell: Double
    let symbol: String

    enum CodingKeys: String, CodingKey {
        case fifteenMin = "15m"
        case last
        case buy
        case sell
        case symbol
    }
}

struct Currencies: Codable {
    var USD: Price? 
    var JPY: Price?
    var EUR: Price?
    var AUD: Price?
}

let usdPrice = Price(fifteenMin: 10, last: 11, buy: 12, sell: 13, symbol: "$")
let jpyPrice = Price(fifteenMin: 10, last: 11, buy: 12, sell: 13, symbol: "¥")
var currencies = Currencies()
currencies.USD = usdPrice


// Encode data
let jsonEncoder = JSONEncoder()
do {
    let jsonData = try jsonEncoder.encode(currencies)
    let jsonString = String(data: jsonData, encoding: .utf8)
    print("JSON String : " + jsonString!)
    do {
        // Decode data to object
        let jsonDecoder = JSONDecoder()
        let currencies = try jsonDecoder.decode(Currencies.self, from: jsonData)

        print("USD: \(currencies.USD)")
        print("JPY: \(currencies.JPY)")
    }
    catch {
    }

}
catch {
}

维护多个数组非常烦人(而且容易出错)。我建议在结构中包含 name

Currency

中添加这一行
var name = ""

对JSON键进行解码后,得到对应的值,将name设置为key

var currenciesArray = [Currency]()

let currencies = try decoder.decode([String: Currency].self, from: jsonData)

for key in currencies.keys.sorted() {
    var currency = currencies[key]!
    currency.name = key
    currenciesArray.append(currency)
}
print(currenciesArray)