如何从 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 数据