I have a struct Endpoint
struct Endpoint {
let responseDecodable: Decodable.Type
let path: String
let queryItems: [URLQueryItem]
}
which is used to construct different api requests using Alamofire:
func fetchData(_ endpoint: Endpoint) {
AF.request(endpoint.url!).responseDecodable(of: endpoint.responseDecodable) { response in
}
}
extension Endpoint {
static func getUser(by id: Int) -> Endpoint {
return Endpoint(
responseDecodable: UsersGet.self,
path: ... ,
queryItems: ... )
}
static func getFriends(by user: User) -> Endpoint {
return Endpoint(
responseDecodable: FriendsGet.self,
path: ... ,
queryItems: ... )
}
The problem is, different endpoint requests give different JSON objects, and I need to specify that type in responseDecodable(of: Decodable.Protocol)
But AF.request in func fetchData
gives me an error: Cannot convert value of type 'Decodable.Type' to expected argument type 'T.Type'
How do I pass that Decodable.Protocol
from Endpoint
without making a generic struct?
Looking back I see that was a silly question but hey
Generic struct that returns type in the endpoint constructor solves the problem.
struct Endpoint<T> where T: Decodable {
let path: String
let queryItems: [URLQueryItem]
}
extension Endpoint {
static func getUser(by id: Int) -> Endpoint<UsersGet> {
return Endpoint<UsersGet>(
path: ... ,
queryItems: ... )
)
}
// same for other endpoints
}
And the fetchData function used like this with generic parameter that is automatically inferred (that's what I wanted)
func fetchData<T: Decodable>(_ endpoint: Endpoint<T>, completion: @escaping (DataResponse<T, AFError>) -> Void) {
AF.request(endpoint.url!).responseDecodable(completionHandler: completion)
}
fetchData(.getFriends(by: user)) { response in
// ...
}