I am trying to understand how much I can use generics in protocols. The idea I have in mind is the following:
protocol Network {
    func fetchCodable<T:Codable>(urlRequest:URLRequest, completion:@escaping (Result<T,Error>)->Void)
}
Then I create a class called AppNetwork that implements the network protocol.
extension AppNetwork:Network{
    func fetchCodable<T>(urlRequest: URLRequest, completion: @escaping (Result<T, Error>) -> Void) where T : Decodable, T : Encodable {
        URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
            if let error = error {
                completion(.failure(error))
                return
            }
            guard let data = data else{
                completion(.failure(AppNetworkError.dataCorrupted))
                return
            }
            do {
                let response = try JSONDecoder().decode(T.self, from: data)
                completion(.success(response))
            }
            catch let decodeError{
                completion(.failure(decodeError))
            }
        }.resume()
    }
This class is part of NetworkHelper that implements functions to retrieve data such as:
class NetworkHelper{
    let network:Network = AppNetwork()
}
...
//MARK:- Public methods
extension NetworkHelper{
    func getVenueDetails(inLocation:String, offset:Int, limit:Int, radius:Int = 1000,completion:(Result<VenueDetailsSearchResult, Error>)->Void){
        guard let foursquareConfig = foursquareConfig else{
            completion(.failure(NetworkHelper.NetworkHelperError.invalidFourSquareConfig))
            return
        }
        var venuesURLString = EndPoints.venueSearch.rawValue + "?"
        venuesURLString += foursquareConfig.getFormattedParams
        venuesURLString += "&near=\(inLocation)&radius=\(radius)&offset=\(offset)&limit=\(limit)"
        guard let venuesURL = URL(string: venuesURLString) else{
            completion(.failure(NetworkHelper.NetworkHelperError.invalidURL))
            return
        }
        let venuesURLRequest = URLRequest(url: venuesURL, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 10)
        network.fetchCodable(urlRequest: venuesURLRequest) { result in
        }
    }
}
In this case a am trying to get a Result but I a get a message error: "Generic parameter 'T' could not be inferred"
How am I supposed to do it if I can do it like that?
Thank you
You'll have to tell the compiler about the type you're expecting.
network.fetchCodable(urlRequest: venuesURLRequest) { (_ result: Result<VenueDetailsSearchResult, Error>) in
    // ...
}
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