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

Posted

技术标签:

【中文标题】如何从 JSON 对象 Swift 4 中检索值【英文标题】:How to retrieve a value from JSON Object Swift 4 【发布时间】:2017-12-04 05:59:25 【问题描述】:

我正在尝试使用 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 循环”并将“USD”、“AUD”等附加到一个数组中,并将货币对象附加到另一个数组中。

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

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

谢谢。

【问题讨论】:

【参考方案1】:

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

Currency中添加这一行

var name = ""

解码JSON后对key进行排序,得到对应的值并将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)

【讨论】:

非常感谢,先生!您的回答非常有帮助!现在它就像一个魅力:)【参考方案2】:

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

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

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

然后像这样追加:

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

附言: 需要在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 

【讨论】:

是的,我正在考虑在 Currency 对象中插入货币名称,但是在 Codable 中我需要使用属性名称作为键来解码 JSON 我不知道该怎么做因为货币名称有JSON 对象中没有键。 我认为您应该创建一个名为 Currency 的结构和另一个名为 Price 的结构(例如),并使用 Price 作为 Currency 的属性,以及一个名为“name”的属性(将是 USD,日元、澳元等)。 检查编辑后的答案。我添加了一个代码,该代码将输出与您提到的类似的 JSON,然后它将 JSON 解码回一个对象。 哦,谢谢你的回答。但是,对我来说仍然不清楚。您创建了两个属性并将它们称为货币名称,但我有 22 种货币..所以我无法在 Currencies 结构中创建 22 个属性也许我误解了您的解释。如果我错了,请纠正我。 也许这不是最好的解决方案,但这就是我可以使用特定 JSON 并使用 Codable 解码的方法。但为什么不呢?您可以使用所有可能的货币(作为可选)创建一个结构并解码所有可用的货币。 (我编辑了答案)

以上是关于如何从 JSON 对象 Swift 4 中检索值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 3 中解析来自 URL 的 JSON 数据

如何从 Swift 3 上的响应字符串中检索标题字段?

检索 JSON 对象 Swift 2

Swift 4 Playground - 从 JSON 获取对象/结果

如何在swift中将json数组保存和检索到用户默认值?

如何从 discord.js 中的 JSON 对象中检索消息作为对象?