使用 Codable 在 Swift 中解析字典数组

Vin*_*nan 5 json swift codable

我有一个来自 API 的 JSON 响应,但我无法弄清楚如何使用 Swift Codable 将其转换为用户对象(单个用户)。这是 JSON(为了便于阅读,删除了一些元素):

{
  "user": [
    {
      "key": "id",
      "value": "093"
    },
    {
      "key": "name",
      "value": "DEV"
    },
    {
      "key": "city",
      "value": "LG"
    },
    {
      "key": "country",
      "value": "IN"
    },
    {
      "key": "group",
      "value": "OPRR"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

Joa*_*son 6

如果你愿意,你可以分两步完成。首先为接收到的json声明一个struct

struct KeyValue: Decodable {
    let key: String
    let value: String
}
Run Code Online (Sandbox Code Playgroud)

然后解码 json 并使用键/值对将结果映射到字典中。

do {
    let result = try JSONDecoder().decode([String: [KeyValue]].self, from: data)

    if let array = result["user"] {
        let dict = array.reduce(into: [:]) { $0[$1.key] = $1.value}
Run Code Online (Sandbox Code Playgroud)

然后将此字典编码为 json 并使用 User 的结构再次返回

struct User: Decodable {
    let id: String
    let name: String
    let group: String
    let city: String
    let country: String
}

let userData = try JSONEncoder().encode(dict)
let user = try JSONDecoder().decode(User.self, from: userData)
Run Code Online (Sandbox Code Playgroud)

整个代码块然后变成

do {
    let decoder = JSONDecoder()
    let result = try decoder.decode([String: [KeyValue]].self, from: data)

    if let array = result["user"] {
        let dict = array.reduce(into: [:]) { $0[$1.key] = $1.value}
        let userData = try JSONEncoder().encode(dict)
        let user = try decoder.decode(User.self, from: userData)
        //...
    }
} catch {
    print(error)
}
Run Code Online (Sandbox Code Playgroud)

有点麻烦,但不需要手动键/属性匹配。