Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

有没有好的方案,把URLSessionDataDelegate更多的协议实现暴露出来 #1620

Merged
merged 6 commits into from
Mar 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Sources/Networking/ImageDownloader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,13 @@ open class ImageDownloader {
authenticationChallengeResponder = self
setupSessionHandler()
}


/// You could set the extra handler before a downloading task starts.
public var extraSessionDelegateHandler:URLSessionDataDelegate? {
set {sessionDelegate.extraHandler = newValue}
get {return sessionDelegate.extraHandler}
}

deinit { session.invalidateAndCancel() }

private func setupSessionHandler() {
Expand Down
41 changes: 41 additions & 0 deletions Sources/Networking/SessionDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class SessionDelegate: NSObject {

private var tasks: [URL: SessionDataTask] = [:]
private let lock = NSLock()
weak var extraHandler: URLSessionDataDelegate?

let onValidStatusCode = Delegate<Int, Bool>()
let onDownloadingFinished = Delegate<(URL, Result<URLResponse, KingfisherError>), Void>()
Expand Down Expand Up @@ -145,6 +146,7 @@ class SessionDelegate: NSObject {
lock.unlock()
task?.forceCancel()
}

}

extension SessionDelegate: URLSessionDataDelegate {
Expand Down Expand Up @@ -259,4 +261,43 @@ extension SessionDelegate: URLSessionDataDelegate {
remove(sessionTask)
sessionTask.onTaskDone.call((result, sessionTask.callbacks))
}


// MARK: - extraHandler
@available(iOS 7.0, OSX 11.0, tvOS 9.0, watchOS 2.0, *)
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
extraHandler?.urlSessionDidFinishEvents?(forBackgroundURLSession: session)
}
func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) {
extraHandler?.urlSession?(session, didBecomeInvalidWithError: error)
}
@available(iOS 11.0, OSX 10.13, tvOS 11.0, watchOS 4.0, *)
func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) {
extraHandler?.urlSession?(session, taskIsWaitingForConnectivity: task)
}
@available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *)
func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) {
extraHandler?.urlSession?(session, task: task, didFinishCollecting: metrics)
}
@available(iOS 9.0, OSX 10.11, tvOS 9.0, watchOS 2.0, *)
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didBecome streamTask: URLSessionStreamTask) {
extraHandler?.urlSession?(session, dataTask: dataTask, didBecome: streamTask)
}
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didBecome downloadTask: URLSessionDownloadTask) {
extraHandler?.urlSession?(session, dataTask: dataTask, didBecome: downloadTask)
}
func urlSession(_ session: URLSession, task: URLSessionTask, needNewBodyStream completionHandler: @escaping (InputStream?) -> Void) {
extraHandler?.urlSession?(session, task: task, needNewBodyStream: completionHandler)
Copy link

@dreampiggy dreampiggy Mar 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you implements the URLSessionDelegate method with completionBlock, you MUST callback the handler, even if you don't have anything logic or nil extraHandler here.

Same as other delegate methods.

}
func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
extraHandler?.urlSession?(session, task: task, didSendBodyData: bytesSent, totalBytesSent: totalBytesSent, totalBytesExpectedToSend: totalBytesExpectedToSend)
}
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, willCacheResponse proposedResponse: CachedURLResponse, completionHandler: @escaping (CachedURLResponse?) -> Void) {
extraHandler?.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) {
extraHandler?.urlSession?(session, task: task, willBeginDelayedRequest: request, completionHandler: completionHandler)
}

}
19 changes: 19 additions & 0 deletions Tests/KingfisherTests/ImageDownloaderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class ImageDownloaderTests: XCTestCase {

var downloader: ImageDownloader!
var modifier = URLModifier()
var expectation: XCTestExpectation?

override class func setUp() {
super.setUp()
Expand Down Expand Up @@ -547,6 +548,18 @@ class ImageDownloaderTests: XCTestCase {
XCTAssertEqual(task?.sessionTask.task.priority, URLSessionTask.highPriority)
waitForExpectations(timeout: 3, handler: nil)
}

func testExtraSessionDelegateHandler() {
expectation = expectation(description: #function)

downloader.extraSessionDelegateHandler = self
let url = testURLs[0]
stub(url, data: testImageData)

downloader.downloadImage(with: url)
waitForExpectations(timeout: 3, handler: nil)
}

}

extension ImageDownloaderTests: ImageDownloaderDelegate {
Expand Down Expand Up @@ -576,3 +589,9 @@ class AsyncURLModifier: AsyncImageDownloadRequestModifier {
}
}
}

extension ImageDownloaderTests: URLSessionDataDelegate {
func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) {
expectation?.fulfill()
}
}