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

时间:2019-09-21 09:27:54

标签: 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"
    }
  ]
}

3 个答案:

答案 0 :(得分:4)

如果需要,可以分两个步骤进行操作。首先为接收的json声明一个结构

struct KeyValue: Decodable {
    let key: String
    let value: String
}

然后解码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}

然后将此字典编码为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)

然后整个代码块变为

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)
}

比较麻烦,但不需要手动进行键/属性匹配。

答案 1 :(得分:0)

您可以尝试这样的结构

struct Model: Codable {
    struct User: Codable {
        let key: String
        let value: String
    }
    let singleuser: [User]
}

答案 2 :(得分:0)

创建具有2个变量的键和值的结构

public struct UserModel: Codable {
    public struct User: Codable {
        public let key: String
        public let value: String
    }
    public let user: [User]
}

之后,使用JSONDecoder解码您的字符串。

func decode(payload: String) {
    do {
        let template = try JSONDecoder().decode(UserModel.self, from: payload.data(using: .utf8)!)
    } catch {
       print(error)
    }
}