kean / Get

Web API client built using async/await
MIT License
943 stars 75 forks source link

Some methods of custom URLSessionDelegate are ignored by APIClient #81

Closed Mrteller closed 7 months ago

Mrteller commented 1 year ago

It is handy we can set our own custom URLSessionDelegate in APIClient init.

        self.api = APIClient(baseURL: baseURL, {
            $0.sessionDelegate = ...
        })

But custom delegate methods are just not called for simple GET/POST queries. Don't think this how it should be. It looks like DataLoader.swift just lacks them.

Particularly in my case (I need to do some SSl pinning) if I add the following code to DataLoader.swift everything begins to work as expected:

    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        userSessionDelegate?.urlSession?(session, didReceive: challenge, completionHandler: completionHandler) ??
        completionHandler(.performDefaultHandling, nil)
    }

It looks like delegation is forwarded only for some subtypes of URLSessionDelegate (URLSessionTaskDelegate, URLSessionDataDelegate, URLSessionDownloadDelegate) but not for the type itself. Just not sure if it will be correct to implement such forwarding for both URLSessionDelegate and it subtypes. That's why made it an issue, not a pull request.

joliejuly commented 1 year ago

I have the same problem. Also, some methods like didFinishWithError are not called neither.

kean commented 11 months ago

I might be wrong because it's been a while, but I think the situation with authentication challenges is that there is a per-session and a per-task delegate method, which are mutually exclusive. I would suggest implementing a per-task one, which is part of the DataLoader implementation:

func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)

It's more powerful/granular, hence why only a task-based method is implemented.