I am trying to pass a model/struct as a parameter in function and passing it to another struct/model with generic type here is my code
---> Function
func getAPICallModelDecodable<T:Codable> (url:String,model:T,
success: @escaping (_ responseObject:T?)->Void,
failure: @escaping (_ error:String) -> Void ,
method:HTTPMethod = .get) {
print(type(of: model))
AF.request(url,method:method).responseDecodable(of: FetchAPI<T(Want to pass model parameter here)>.self) { respons in
print(respons)
switch respons.result {
case .success(let data):
if data.flag! {
success(data.data)
}
case .failure(let error):
failure(error.localizedDescription)
}
}
}
---> FetchAPI Struct
struct FetchAPI<T:Codable>:Codable {
var flag: Bool?
var statusCode: Int?
var message: String?
var data: T?
enum CodingKeys: String, CodingKey {
case flag = "Flag"
case statusCode = "StatusCode"
case message = "Message"
case data = "Data"
}
}
Model parameter can be any codable structure
CodePudding user response:
Currently your function getAPICallModelDecodable
is defined in such a way that you have to pass in a model of type T. But if I understand it correctly, you only want to pass in (define) the type T.
For this you have to change the function as follows:
func getAPICallModelDecodable<T:Codable> (url: String, type: T.Type,
success: @escaping (_ responseObject:T?)->Void,
failure: @escaping (_ error:String) -> Void ,
method:HTTPMethod = .get)
In the function body you can use T e.g. simply like this:
AF.request(url,method:method).responseDecodable(of: FetchAPI<T>.self)
The function call would then look like this:
getAPICallModelDecodable(url: ..., type: Model.self, ...)
CodePudding user response:
You don't have to pass the model or the type of the model explicitly, the compiler can deduce that from when you call the method.
So your func declaration should be
func getAPICallModelDecodable<T:Codable>(url:String,
success: @escaping (_ responseObject: T?) -> Void,
failure: @escaping (_ error: String) -> Void ,
method:HTTPMethod = .get) {
and the request call should be
AF.request(url,method:method).responseDecodable(of: FetchAPI<T>.self)
I don't use Alamofire myself so here is a more complete example using a quick implementation using URLSession
and a model Test
that conforms to Codable
func makeApiCall<T: Codable>(url: URL,
success: @escaping (_ responseObject: T?) -> Void,
failure: @escaping (_ error: String) -> Void) {
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
failure("\(error)")
}
if let data = data {
do {
let result = try JSONDecoder().decode(FetchAPI<T>.self, from: data)
success(result.data)
} catch {
failure("\(error)")
}
} else {
failure("No error, no data")
}
}
.resume()
}
func success(_ model: Test?) {}
func failure(_ error: String) {}
let url = URL(string: "http://someurl")!
makeApiCall(url: url, success: { success($0) }, failure: { failure($0) })