Приведение к объекту с помощью Codable - PullRequest
0 голосов
/ 10 октября 2018

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

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

]

Где отправленное обратно data может варьироваться.Иногда он может содержать User с, иногда Comment с и т. Д. Поэтому я хочу создать 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 Ответ

0 голосов
/ 10 октября 2018

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

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

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

struct User: Codable {
    var name: String
}

и декодировать ее ...

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

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

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

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

...