Вы можете просто использовать containers
для декодирования вложенных данных с помощью Decodable
, т.е.
struct Info: Decodable {
let id: String
let status: String
let personName: String
let companyName: String
enum CodingKeys: String, CodingKey {
case id, status
case person, administration
case company
case name
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
id = try values.decode(String.self, forKey: .id)
status = try values.decode(String.self, forKey: .status)
//Decoding personName
let person = try values.nestedContainer(keyedBy: CodingKeys.self, forKey: .person)
let administration = try person.nestedContainer(keyedBy: CodingKeys.self, forKey: .administration)
personName = try administration.decode(String.self, forKey: .name)
//Decoding companyName
let company = try values.nestedContainer(keyedBy: CodingKeys.self, forKey: .company)
companyName = try company.decode(String.self, forKey: .name)
}
}
Пример:
IВы расшифровали JSON
, который вы указали выше, то есть
if let data = json.data(using: .utf8) {
let info = try? JSONDecoder().decode(Info.self, from: data)
print(info)
}
Выходные данные:
(id: "123", status: "ok", personName: "John", companyName: "Test")
Вы можетевыделите CodingKeys
для всех различных уровней по вашему желанию.Я сохранил их на одном уровне для простоты.
Предложение: Попробуйте использовать optional types
с Codable
.Это связано с тем, что ответ API
может быть неожиданным.И если вы не получите никакой ожидаемой пары ключ-значение, вы можете получить nil
при создании объекта.