Приведение к объекту с помощью Codable

Все мои ответы JSON имеют одинаковую структуру:

"success": <http code>,
"data": [

]

Где data отправлено обратно может варьироваться. Иногда это может содержать Userс, иногда Comments и т. д. Поэтому я хочу создать Codable struct это гибкий для обработки различных типов объектов, отправляемых обратно в data массив.

Вот мой ток struct:

struct BasicResponse: Codable {
    let success: Int
    let data: [User]
}

Как вы можете видеть, он в настоящее время обрабатывает только User данные отправляются обратно.

Затем я читаю данные JSON следующим образом (через Alamofire/Moya):

var users = [User]()

let results = try JSONDecoder().decode(BasicResponse.self, from: response.data)

self.users.append(contentsOf: results.data)

Как я могу изменить свой struct файл, чтобы быть более гибким, и как бы я затем привести JSON-ответ на нужный объект?

1 ответ

Решение

Так что, не проходя много циклов проектирования и без промедления, я бы подумал, например, попробовать общую поддержку Swift...

struct BasicResponse<DataType>: Codable where DataType: Codable {
    let success: Int
    let data: [DataType]
}

Тогда вам просто нужно определить реализацию DataTypeвы хотите использовать

struct User: Codable {
    var name: String
}

И расшифровать это...

let decoder = JSONDecoder()
let response = try decoder.decode(BasicResponse<User>.self, from: data)
print(response.data[0].name)

Теперь я просто бросил это на игровую площадку и протестировал с некоторыми основными данными...

struct User: Codable {
    var name: String
}

struct BasicResponse<T>: Codable where T: Codable {
    let success: Int
    let data: [T]
}

let data = "{\"success\": 200, \"data\": [ { \"name\":\"hello\" }]}".data(using: .utf8)!

let decoder = JSONDecoder()
do {
    let response = try decoder.decode(BasicResponse<User>.self, from: data)
    response.data[0].name
} catch let error {
    print(error)
}

Возможно, вам придется "помассировать" дизайн, чтобы лучше удовлетворить ваши потребности, но это может дать вам место для начала

Другие вопросы по тегам