当父名称不同时解码 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)
}