【问题标题】:Decoding JSON structure in Swift when parent name varies?当父名称变化时在Swift中解码JSON结构?
【发布时间】:2022-01-03 19:11:46
【问题描述】:

我正在进行 API 调用,它返回以下 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
}

这将解码这个特定的示例,但如果我获取其他硬币,它将无法工作,因为字符串名称不同,因此它们不会匹配。我确定我在这里遗漏了一些简单的东西,但是有人知道我该如何解决这个问题吗?

【问题讨论】:

  • 您是否也在使用英镑以外的其他货币?

标签: json swift decoding


【解决方案1】:

如果名称可以是任意字符串,则需要解码[String: Coin] 字典。只要Coin 是可编码的,[String: Coin] 也是可编码的。

【讨论】:

  • 只是添加到这个。一旦你有了你的 [String : Coin] 字典,你就可以在必要时将它转换成你想要的属性。所以你可以从字典中取出以太坊和比特币的键值。
【解决方案2】:

我认为使用 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)
}

【讨论】:

    猜你喜欢
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多