I am facing a challenge regarding mapping a generic api responses against a model class using codable or object mapper. Suppose I have these api responses against different 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
}
here user, locations and countries are separate codable/mapper classes.
I will have to construct a class like this
struct APIResponse : Codable {
let success : Bool?
let http_response : Int?
let code : Int?
let data : ??
}
How I will construct my base class to handle these responses using one class or I will have construct different classes just to change "data" type according to value?
Any kind of help or suggestion will be highly appreciated.
Thanks
Make generic constraint for you struct which says that T has to conform to Decodable and then use this type for specifing type of data
struct APIResponse<T: Decodable>: Decodable {
var code, httpResponse: Int
var success: Bool
var data: T
}
struct User: Decodable {
var name: String
}
note that I changed name of httpResponse parameter since I'm using keyDecodingStrategy which converts http_response to httpResponse
Then while decoding specify type of T
Single object
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) }
Array of objects
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) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With