Browse Source

Extend `URLSessionDataDelegate` for more handler

727881945@qq.com 5 years ago
parent
commit
d85ea54536

+ 6 - 1
Sources/Networking/ImageDownloader.swift

@@ -164,7 +164,12 @@ open class ImageDownloader {
         authenticationChallengeResponder = self
         authenticationChallengeResponder = self
         setupSessionHandler()
         setupSessionHandler()
     }
     }
-
+    
+    /// You could set the extral handler before a downloading task starts.
+    public func addExtraSessionDelegateHandler(_ handler: URLSessionDataDelegate) {
+        sessionDelegate.extralHandler = handler
+    }
+    
     deinit { session.invalidateAndCancel() }
     deinit { session.invalidateAndCancel() }
 
 
     private func setupSessionHandler() {
     private func setupSessionHandler() {

+ 37 - 0
Sources/Networking/SessionDelegate.swift

@@ -45,6 +45,7 @@ class SessionDelegate: NSObject {
 
 
     private var tasks: [URL: SessionDataTask] = [:]
     private var tasks: [URL: SessionDataTask] = [:]
     private let lock = NSLock()
     private let lock = NSLock()
+    public var extralHandler: URLSessionDataDelegate?
 
 
     let onValidStatusCode = Delegate<Int, Bool>()
     let onValidStatusCode = Delegate<Int, Bool>()
     let onDownloadingFinished = Delegate<(URL, Result<URLResponse, KingfisherError>), Void>()
     let onDownloadingFinished = Delegate<(URL, Result<URLResponse, KingfisherError>), Void>()
@@ -259,4 +260,40 @@ extension SessionDelegate: URLSessionDataDelegate {
         remove(sessionTask)
         remove(sessionTask)
         sessionTask.onTaskDone.call((result, sessionTask.callbacks))
         sessionTask.onTaskDone.call((result, sessionTask.callbacks))
     }
     }
+    
+    
+    // MARK: - ExtralHandler
+    func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
+        extralHandler?.urlSessionDidFinishEvents?(forBackgroundURLSession: session)
+    }
+    func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) {
+        extralHandler?.urlSession?(session, didBecomeInvalidWithError: error)
+    }
+    @available(iOS 11.0, OSX 10.13, tvOS 11.0, watchOS 4.0, *)
+    func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) {
+        extralHandler?.urlSession?(session, taskIsWaitingForConnectivity: task)
+    }
+    func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) {
+        extralHandler?.urlSession?(session, task: task, didFinishCollecting: metrics)
+    }
+    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didBecome streamTask: URLSessionStreamTask) {
+        extralHandler?.urlSession?(session, dataTask: dataTask, didBecome: streamTask)
+    }
+    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didBecome downloadTask: URLSessionDownloadTask) {
+        extralHandler?.urlSession?(session, dataTask: dataTask, didBecome: downloadTask)
+    }
+    func urlSession(_ session: URLSession, task: URLSessionTask, needNewBodyStream completionHandler: @escaping (InputStream?) -> Void) {
+        extralHandler?.urlSession?(session, task: task, needNewBodyStream: completionHandler)
+    }
+    func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
+        extralHandler?.urlSession?(session, task: task, didSendBodyData: bytesSent, totalBytesSent: totalBytesSent, totalBytesExpectedToSend: totalBytesExpectedToSend)
+    }
+    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, willCacheResponse proposedResponse: CachedURLResponse, completionHandler: @escaping (CachedURLResponse?) -> Void) {
+        extralHandler?.urlSession?(session, dataTask: dataTask, willCacheResponse: proposedResponse, completionHandler: completionHandler)
+    }
+    @available(iOS 11.0, OSX 10.13, tvOS 11.0, watchOS 4.0, *)
+    func urlSession(_ session: URLSession, task: URLSessionTask, willBeginDelayedRequest request: URLRequest, completionHandler: @escaping (URLSession.DelayedRequestDisposition, URLRequest?) -> Void) {
+        extralHandler?.urlSession?(session, task: task, willBeginDelayedRequest: request, completionHandler: completionHandler)
+    }
+    
 }
 }

+ 20 - 0
Tests/KingfisherTests/ImageDownloaderTests.swift

@@ -32,6 +32,7 @@ class ImageDownloaderTests: XCTestCase {
 
 
     var downloader: ImageDownloader!
     var downloader: ImageDownloader!
     var modifier = URLModifier()
     var modifier = URLModifier()
+    var expectation: XCTestExpectation?
 
 
     override class func setUp() {
     override class func setUp() {
         super.setUp()
         super.setUp()
@@ -547,6 +548,19 @@ class ImageDownloaderTests: XCTestCase {
         XCTAssertEqual(task?.sessionTask.task.priority, URLSessionTask.highPriority)
         XCTAssertEqual(task?.sessionTask.task.priority, URLSessionTask.highPriority)
         waitForExpectations(timeout: 3, handler: nil)
         waitForExpectations(timeout: 3, handler: nil)
     }
     }
+    
+    func testExtralSessionDelegateHandler() {
+        expectation = expectation(description: #function)
+       
+        downloader.addExtraSessionDelegateHandler(self)
+       
+        let url = testURLs[0]
+        stub(url, data: testImageData)
+        
+        downloader.downloadImage(with: url)
+        waitForExpectations(timeout: 3, handler: nil)
+    }
+    
 }
 }
 
 
 extension ImageDownloaderTests: ImageDownloaderDelegate {
 extension ImageDownloaderTests: ImageDownloaderDelegate {
@@ -576,3 +590,9 @@ class AsyncURLModifier: AsyncImageDownloadRequestModifier {
         }
         }
     }
     }
 }
 }
+
+extension ImageDownloaderTests: URLSessionDataDelegate {
+    func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) {
+        expectation?.fulfill()
+    }
+}