Improvement download operation for priority and some protect (#2208)
* Add a cache check for 304 response when using NSURLCache * Remove the extra cost to nil the imageData because at this time operation is already been cancelled or done * Fix download operation may not marked as finished when data task create failed * A little code reorder * Adopt the priority options to change URLSessionTask's priority
This commit is contained in:
parent
bd22ad8725
commit
2646b3a1f2
|
@ -136,7 +136,7 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
NSURLSession *session = self.unownedSession;
|
NSURLSession *session = self.unownedSession;
|
||||||
if (!self.unownedSession) {
|
if (!session) {
|
||||||
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
|
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
|
||||||
sessionConfig.timeoutIntervalForRequest = 15;
|
sessionConfig.timeoutIntervalForRequest = 15;
|
||||||
|
|
||||||
|
@ -145,10 +145,10 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary;
|
||||||
* We send nil as delegate queue so that the session creates a serial operation queue for performing all delegate
|
* We send nil as delegate queue so that the session creates a serial operation queue for performing all delegate
|
||||||
* method calls and completion handler calls.
|
* method calls and completion handler calls.
|
||||||
*/
|
*/
|
||||||
self.ownedSession = [NSURLSession sessionWithConfiguration:sessionConfig
|
session = [NSURLSession sessionWithConfiguration:sessionConfig
|
||||||
delegate:self
|
delegate:self
|
||||||
delegateQueue:nil];
|
delegateQueue:nil];
|
||||||
session = self.ownedSession;
|
self.ownedSession = session;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.options & SDWebImageDownloaderIgnoreCachedResponse) {
|
if (self.options & SDWebImageDownloaderIgnoreCachedResponse) {
|
||||||
|
@ -170,10 +170,19 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary;
|
||||||
self.dataTask = [session dataTaskWithRequest:self.request];
|
self.dataTask = [session dataTaskWithRequest:self.request];
|
||||||
self.executing = YES;
|
self.executing = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
[self.dataTask resume];
|
|
||||||
|
|
||||||
if (self.dataTask) {
|
if (self.dataTask) {
|
||||||
|
[self.dataTask resume];
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wunguarded-availability"
|
||||||
|
if ([self.dataTask respondsToSelector:@selector(setPriority:)]) {
|
||||||
|
if (self.options & SDWebImageDownloaderHighPriority) {
|
||||||
|
self.dataTask.priority = NSURLSessionTaskPriorityHigh;
|
||||||
|
} else if (self.options & SDWebImageDownloaderLowPriority) {
|
||||||
|
self.dataTask.priority = NSURLSessionTaskPriorityLow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma clang diagnostic pop
|
||||||
for (SDWebImageDownloaderProgressBlock progressBlock in [self callbacksForKey:kProgressCallbackKey]) {
|
for (SDWebImageDownloaderProgressBlock progressBlock in [self callbacksForKey:kProgressCallbackKey]) {
|
||||||
progressBlock(0, NSURLResponseUnknownLength, self.request.URL);
|
progressBlock(0, NSURLResponseUnknownLength, self.request.URL);
|
||||||
}
|
}
|
||||||
|
@ -182,7 +191,9 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary;
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStartNotification object:weakSelf];
|
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStartNotification object:weakSelf];
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
[self callCompletionBlocksWithError:[NSError errorWithDomain:NSURLErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Task can't be initialized"}]];
|
[self callCompletionBlocksWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorUnknown userInfo:@{NSLocalizedDescriptionKey : @"Task can't be initialized"}]];
|
||||||
|
[self done];
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SD_UIKIT
|
#if SD_UIKIT
|
||||||
|
@ -237,19 +248,6 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary;
|
||||||
});
|
});
|
||||||
self.dataTask = nil;
|
self.dataTask = nil;
|
||||||
|
|
||||||
NSOperationQueue *delegateQueue;
|
|
||||||
if (self.unownedSession) {
|
|
||||||
delegateQueue = self.unownedSession.delegateQueue;
|
|
||||||
} else {
|
|
||||||
delegateQueue = self.ownedSession.delegateQueue;
|
|
||||||
}
|
|
||||||
if (delegateQueue) {
|
|
||||||
NSAssert(delegateQueue.maxConcurrentOperationCount == 1, @"NSURLSession delegate queue should be a serial queue");
|
|
||||||
[delegateQueue addOperationWithBlock:^{
|
|
||||||
weakSelf.imageData = nil;
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.ownedSession) {
|
if (self.ownedSession) {
|
||||||
[self.ownedSession invalidateAndCancel];
|
[self.ownedSession invalidateAndCancel];
|
||||||
self.ownedSession = nil;
|
self.ownedSession = nil;
|
||||||
|
@ -283,9 +281,15 @@ didReceiveResponse:(NSURLResponse *)response
|
||||||
expected = expected > 0 ? expected : 0;
|
expected = expected > 0 ? expected : 0;
|
||||||
self.expectedSize = expected;
|
self.expectedSize = expected;
|
||||||
self.response = response;
|
self.response = response;
|
||||||
|
NSInteger statusCode = [response respondsToSelector:@selector(statusCode)] ? ((NSHTTPURLResponse *)response).statusCode : 200;
|
||||||
|
BOOL valid = statusCode < 400;
|
||||||
|
//'304 Not Modified' is an exceptional one. It should be treated as cancelled if no cache data
|
||||||
|
//URLSession current behavior will return 200 status code when the server respond 304 and URLCache hit. But this is not a standard behavior and we just add a check
|
||||||
|
if (statusCode == 304 && !self.cachedData) {
|
||||||
|
valid = NO;
|
||||||
|
}
|
||||||
|
|
||||||
//'304 Not Modified' is an exceptional one. It should be treated as cancelled.
|
if (valid) {
|
||||||
if (![response respondsToSelector:@selector(statusCode)] || (((NSHTTPURLResponse *)response).statusCode < 400 && ((NSHTTPURLResponse *)response).statusCode != 304)) {
|
|
||||||
for (SDWebImageDownloaderProgressBlock progressBlock in [self callbacksForKey:kProgressCallbackKey]) {
|
for (SDWebImageDownloaderProgressBlock progressBlock in [self callbacksForKey:kProgressCallbackKey]) {
|
||||||
progressBlock(0, expected, self.request.URL);
|
progressBlock(0, expected, self.request.URL);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue