当父名称不同时解码 Swift 中的 JSON 结构?
Decoding JSON structure in Swift when parent name varies?
我正在进行 API 调用,其中 returns 以下 JSON 结构(关于各种加密货币的价格信息):
{
"bitcoin": {
"gbp": 34532
},
"ethereum": {
"gbp": 2789.08
}
}
我用来解码此 JSON 的结构如下所示:
struct Coin: Codable {
let gbp: Double
enum CodingKeys: String, CodingKey {
case gbp
}
}
JSON 没有被解码,因为返回的每个 JSON 元素的父元素是加密货币的名称,但这会根据调用的内容而改变。由于名称总是在变化,我不确定如何在结构中创建一个变量来映射每个父级。例如。对于这个例子,我可以制作这样的结构:
struct AllCoins: Codable {
let bitcoin, ethereum: Coin
}
这将解码这个特定示例,但如果我获取其他硬币,它将无法工作,因为字符串名称不同,因此它们将不匹配。我确定我在这里遗漏了一些简单的东西,但是有人知道我该如何解决这个问题吗?
如果名字可以是任意字符串,你想解码[String: Coin]
字典。只要 Coin
是 Codable,[String: Coin]
也是 Codable。
我认为用 Codable
解码 JSON 比用传统的 JSONSerialization
解码更费力。只要结构总是
{"<name>":
{"<base>": <value>}
}
你可以用这段代码解码任何货币和任何基数,结果是一个Coin
的数组
let jsonString = """
{
"bitcoin": {
"gbp": 34532
},
"ethereum": {
"gbp": 2789.08
}
}
"""
struct Coin {
let name : String
let base : String
let value : Double
}
var coins = [Coin]()
do {
let result = try JSONSerialization.jsonObject(with: Data(jsonString.utf8)) as! [String:[String:Double]]
coins = result.compactMap{ key, rate in
guard let base = rate.keys.first else { return nil }
return Coin(name: key, base: base, value: rate[base]!)
}
print(coins)
} catch {
print(error)
}
我正在进行 API 调用,其中 returns 以下 JSON 结构(关于各种加密货币的价格信息):
{
"bitcoin": {
"gbp": 34532
},
"ethereum": {
"gbp": 2789.08
}
}
我用来解码此 JSON 的结构如下所示:
struct Coin: Codable {
let gbp: Double
enum CodingKeys: String, CodingKey {
case gbp
}
}
JSON 没有被解码,因为返回的每个 JSON 元素的父元素是加密货币的名称,但这会根据调用的内容而改变。由于名称总是在变化,我不确定如何在结构中创建一个变量来映射每个父级。例如。对于这个例子,我可以制作这样的结构:
struct AllCoins: Codable {
let bitcoin, ethereum: Coin
}
这将解码这个特定示例,但如果我获取其他硬币,它将无法工作,因为字符串名称不同,因此它们将不匹配。我确定我在这里遗漏了一些简单的东西,但是有人知道我该如何解决这个问题吗?
如果名字可以是任意字符串,你想解码[String: Coin]
字典。只要 Coin
是 Codable,[String: Coin]
也是 Codable。
我认为用 Codable
解码 JSON 比用传统的 JSONSerialization
解码更费力。只要结构总是
{"<name>":
{"<base>": <value>}
}
你可以用这段代码解码任何货币和任何基数,结果是一个Coin
let jsonString = """
{
"bitcoin": {
"gbp": 34532
},
"ethereum": {
"gbp": 2789.08
}
}
"""
struct Coin {
let name : String
let base : String
let value : Double
}
var coins = [Coin]()
do {
let result = try JSONSerialization.jsonObject(with: Data(jsonString.utf8)) as! [String:[String:Double]]
coins = result.compactMap{ key, rate in
guard let base = rate.keys.first else { return nil }
return Coin(name: key, base: base, value: rate[base]!)
}
print(coins)
} catch {
print(error)
}