Browse Source

Merge pull request #2225 from onevcat/fix/async-auth-challenge

Turn the AuthenticationChallengeResponsible protocol to async style
Wei Wang 1 year ago
parent
commit
8e03bb4e07

+ 20 - 19
Sources/Networking/AuthenticationChallengeResponsable.swift

@@ -40,15 +40,15 @@ public protocol AuthenticationChallengeResponsible: AnyObject {
     /// - Parameters:
     ///   - downloader: The downloader that receives this challenge.
     ///   - challenge: An object that contains the request for authentication.
-    ///   - completionHandler: A handler that your delegate method must call.
+    /// - Returns: The challenge disposition on how the challenge should be handled, and the credential if the
+    /// disposition is `.useCredential`.
     ///
-    /// > This method is a forward from `URLSessionDelegate.urlSession(:didReceiveChallenge:completionHandler:)`.
+    /// > This method is a forward from `URLSessionDelegate.urlSession(_:didReceive:completionHandler:)`.
     /// > Please refer to the documentation of it in `URLSessionDelegate`.
     func downloader(
         _ downloader: ImageDownloader,
-        didReceive challenge: URLAuthenticationChallenge,
-        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
-    )
+        didReceive challenge: URLAuthenticationChallenge
+    ) async -> (URLSession.AuthChallengeDisposition, URLCredential?)
 
     /// Called when a task level authentication challenge is received. 
     ///
@@ -59,40 +59,41 @@ public protocol AuthenticationChallengeResponsible: AnyObject {
     ///   - downloader: The downloader that receives this challenge.
     ///   - task: The task whose request requires authentication.
     ///   - challenge: An object that contains the request for authentication.
-    ///   - completionHandler: A handler that your delegate method must call.
+    /// - Returns: The challenge disposition on how the challenge should be handled, and the credential if the
+    /// disposition is `.useCredential`.
+    ///
+    /// > This method is a forward from `URLSessionDataDelegate.urlSession(_:dataTask:didReceive:completionHandler:)`.
+    /// > Please refer to the documentation of it in `URLSessionDataDelegate`.
     func downloader(
         _ downloader: ImageDownloader,
         task: URLSessionTask,
-        didReceive challenge: URLAuthenticationChallenge,
-        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
-    )
+        didReceive challenge: URLAuthenticationChallenge
+    ) async -> (URLSession.AuthChallengeDisposition, URLCredential?)
 }
 
 extension AuthenticationChallengeResponsible {
 
     public func downloader(
         _ downloader: ImageDownloader,
-        didReceive challenge: URLAuthenticationChallenge,
-        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
+        didReceive challenge: URLAuthenticationChallenge
+    ) async -> (URLSession.AuthChallengeDisposition, URLCredential?)
     {
         if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
             if let trustedHosts = downloader.trustedHosts, trustedHosts.contains(challenge.protectionSpace.host) {
                 let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
-                completionHandler(.useCredential, credential)
-                return
+                return (.useCredential, credential)
             }
         }
 
-        completionHandler(.performDefaultHandling, nil)
+        return (.performDefaultHandling, nil)
     }
-
+    
     public func downloader(
         _ downloader: ImageDownloader,
         task: URLSessionTask,
-        didReceive challenge: URLAuthenticationChallenge,
-        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
-    {
-        completionHandler(.performDefaultHandling, nil)
+        didReceive challenge: URLAuthenticationChallenge
+    ) async -> (URLSession.AuthChallengeDisposition, URLCredential?) {
+        (.performDefaultHandling, nil)
     }
 
 }

+ 2 - 3
Sources/Networking/ImageDownloader.swift

@@ -237,11 +237,10 @@ open class ImageDownloader {
 
     private func setupSessionHandler() {
         sessionDelegate.onReceiveSessionChallenge.delegate(on: self) { (self, invoke) in
-            self.authenticationChallengeResponder?.downloader(self, didReceive: invoke.1, completionHandler: invoke.2)
+            await (self.authenticationChallengeResponder ?? self).downloader(self, didReceive: invoke.1)
         }
         sessionDelegate.onReceiveSessionTaskChallenge.delegate(on: self) { (self, invoke) in
-            self.authenticationChallengeResponder?.downloader(
-                self, task: invoke.1, didReceive: invoke.2, completionHandler: invoke.3)
+            await (self.authenticationChallengeResponder ?? self).downloader(self, task: invoke.1, didReceive: invoke.2)
         }
         sessionDelegate.onValidStatusCode.delegate(on: self) { (self, code) in
             (self.delegate ?? self).isValidStatusCode(code, for: self)

+ 12 - 13
Sources/Networking/SessionDelegate.swift

@@ -34,15 +34,13 @@ open class SessionDelegate: NSObject {
 
     typealias SessionChallengeFunc = (
         URLSession,
-        URLAuthenticationChallenge,
-        (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
+        URLAuthenticationChallenge
     )
 
     typealias SessionTaskChallengeFunc = (
         URLSession,
         URLSessionTask,
-        URLAuthenticationChallenge,
-        (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
+        URLAuthenticationChallenge
     )
 
     private var tasks: [URL: SessionDataTask] = [:]
@@ -53,8 +51,8 @@ open class SessionDelegate: NSObject {
     let onDownloadingFinished = Delegate<(URL, Result<URLResponse, KingfisherError>), Void>()
     let onDidDownloadData = Delegate<SessionDataTask, Data?>()
 
-    let onReceiveSessionChallenge = Delegate<SessionChallengeFunc, Void>()
-    let onReceiveSessionTaskChallenge = Delegate<SessionTaskChallengeFunc, Void>()
+    let onReceiveSessionChallenge = Delegate<SessionChallengeFunc, (URLSession.AuthChallengeDisposition, URLCredential?)>()
+    let onReceiveSessionTaskChallenge = Delegate<SessionTaskChallengeFunc, (URLSession.AuthChallengeDisposition, URLCredential?)>()
 
     func add(
         _ dataTask: URLSessionDataTask,
@@ -226,21 +224,22 @@ extension SessionDelegate: URLSessionDataDelegate {
 
     open func urlSession(
         _ session: URLSession,
-        didReceive challenge: URLAuthenticationChallenge,
-        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
+        didReceive challenge: URLAuthenticationChallenge
+    ) async -> (URLSession.AuthChallengeDisposition, URLCredential?)
     {
-        onReceiveSessionChallenge.call((session, challenge, completionHandler))
+        await onReceiveSessionChallenge.callAsync((session, challenge)) ?? (.performDefaultHandling, nil)
     }
-
+    
     open func urlSession(
         _ session: URLSession,
         task: URLSessionTask,
-        didReceive challenge: URLAuthenticationChallenge,
-        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
+        didReceive challenge: URLAuthenticationChallenge
+    ) async -> (URLSession.AuthChallengeDisposition, URLCredential?)
     {
-        onReceiveSessionTaskChallenge.call((session, task, challenge, completionHandler))
+        await onReceiveSessionTaskChallenge.callAsync((session, task, challenge)) ?? (.performDefaultHandling, nil)
     }
     
+    
     open func urlSession(
         _ session: URLSession,
         task: URLSessionTask,