Me enfrento a un desafío con respecto al mapeo de respuestas de API genéricas contra una clase modelo usando un mapeador de objetos o codificable. Supongamos que tengo estas respuestas de api contra diferentes apis.
{ "code" : 0, "http_response" : 200, "success" : true, "data" : user } { "code" : 0, "http_response" : 200, "success" : true, "data" : locations } { "code" : 0, "http_response" : 200, "success" : true, "data" : countries }aquí el usuario, las ubicaciones y los países son clases codificables/mapeadores separadas.
Tendré que construir una clase como esta.
struct APIResponse : Codable { let success : Bool? let http_response : Int? let code : Int? let data : ?? }¿Cómo construiré mi clase base para manejar estas respuestas usando una clase o tendré que construir diferentes clases solo para cambiar el tipo de "datos" según el valor?
Cualquier tipo de ayuda o sugerencia será muy apreciada.
Gracias
Haga una restricción genérica para su estructura que dice que T tiene que cumplir con Decodable y luego use este tipo para especificar el tipo de data
struct APIResponse<T: Decodable>: Decodable { var code, httpResponse: Int var success: Bool var data: T } struct User: Decodable { var name: String } tenga en cuenta que cambié el nombre del parámetro httpResponse ya que estoy usando keyDecodingStrategy que convierte http_response a httpResponse
Luego, mientras decodifica, especifique el tipo de T
Objeto único
let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase do { let responses = try decoder.decode([APIResponse<User>].self, from: data) let user = responses[0].data /* data of type `User` of specific response */ } catch { print(error) }Matriz de objetos
let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase do { let responses = try decoder.decode([APIResponse<[User]>].self, from: data) let users = responses[0].data /* data of type `[User]` of specific response */ } catch { print(error) }Su método de decodificación y APIResponse se verán así considerando user , los countries y las locations son decodificables,
struct APIResponse<T: Decodable>: Decodable { var data: T? var code: Int var success: Bool var http_response: Int } func decode<T: Decodable>(data: Data, ofType: T.Type) -> T? { do { let decoder = JSONDecoder() let res = try decoder.decode(APIResponse<T>.self, from: data) return res.data } catch let parsingError { print("Error", parsingError) } return nil }Uso
let data = Data() // From the network api //User let user = decode(data, ofType: User.self) // Countries let countries = decode(data, ofType: [Country].self) // Locations let locations = decode(data, ofType: [Location].self)