iosswiftxcodeurlsessionnsurlsessiondatatask

Ambiguous use of 'dataTask(with:completionHandler:)'


I updated the Xcode to 14.3 and when I tried to run a project, I am getting this error: "Ambiguous use of 'dataTask(with:completionHandler:)'"

Do you know how I can fix this issue ?

extension URLSession: URLSessionProtocol {
    func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask {
        return dataTask(with: url, completionHandler: completionHandler) as URLSessionDataTask
    }
}
protocol URLSessionProtocol {
associatedtype dataTaskProtocolType: URLSessionDataTaskProtocol
func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> dataTaskProtocolType

func dataTask(with request: URLRequest, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> dataTaskProtocolType }

This is my NetworkManager, where I got the following error:

"Value of type 'T.URLSessionDataTaskProtocol' has no member 'resume'"

class NetworkManager<T: URLSessionProtocol> {

let session: T

required init(session: T) {
    self.session = session
}

/// Errors that will be generated by the HTTPManager
enum HTTPError: Error {
    case invalidURL
    case noInternet
    case invalidResponse(Data?, URLResponse?)
}

///  Get data through an API call using a URL, returning a result type
///
/// - Parameters:
///   - url: A URL represting the location of the resource
///   - completionBlock: A completion closure returning the result type
public func get(url: URL, completionBlock: @escaping (Result<Data, Error>) -> Void) {
    // make sure we pull new data each time
    let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 60)
    
    let task = session.dataTask(with: request) { data, response, error in
        guard error == nil else {
            completionBlock(.failure(error!))
            return
        }
        
        guard
            let _ = data,
            let httpResponse = response as? HTTPURLResponse,
            200 ..< 300 ~= httpResponse.statusCode else {
                if let data = data {
                    completionBlock(.success(data))
                } else {
                    completionBlock(.failure(HTTPError.invalidResponse(data, response)))
                }
                return
            }
        // if passed guard
        if let data = data {
            completionBlock(.success(data))
        }
    }
    task.resume()
}}

Solution

  • Here's the fix:

    protocol URLSessionDataTaskProtocol {
        func resume()
    }
    
    protocol URLSessionProtocol {
        func dataTask(with request: URLRequest, completionHandler: @escaping @Sendable (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTaskProtocol
        func dataTask(with url: URL, completionHandler: @escaping @Sendable (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTaskProtocol
    }
    
    extension URLSessionDataTask: URLSessionDataTaskProtocol { }
    extension URLSession: URLSessionProtocol {
        func dataTask(with request: URLRequest, completionHandler: @escaping @Sendable (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTaskProtocol {
            self.dataTask(with: request, completionHandler: completionHandler) as URLSessionDataTask
        }
    
        func dataTask(with url: URL, completionHandler: @escaping @Sendable (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTaskProtocol {
            self.dataTask(with: url, completionHandler: completionHandler) as URLSessionDataTask
        }
    }