Разбор массива словарей в Swift с использованием Codable - PullRequest
2 голосов
/ 21 сентября 2019

У меня есть ответ JSON от API, и я не могу понять, как преобразовать его в объект пользователя (одного пользователя) с помощью 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 ]

3 голосов
/ 21 сентября 2019

Вы можете сделать это в два этапа, если хотите.Сначала объявите структуру для полученного 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и обратно с использованием структуры для пользователя

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

Немного громоздко, но не требуется ручное сопоставление ключа / свойства.

0 голосов
/ 21 сентября 2019

Создайте структуру с ключом с двумя переменными и значением

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)
    }
}
0 голосов
/ 21 сентября 2019

вы можете попробовать структуру с таким

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