diff --git a/SDWebImage/SDImageLoader.h b/SDWebImage/SDImageLoader.h index a69f7c53..136ac9e4 100644 --- a/SDWebImage/SDImageLoader.h +++ b/SDWebImage/SDImageLoader.h @@ -85,4 +85,16 @@ FOUNDATION_EXPORT UIImage * _Nullable SDImageLoaderDecodeProgressiveImageData(NS progress:(nullable SDImageLoaderProgressBlock)progressBlock completed:(nullable SDImageLoaderCompletedBlock)completedBlock; + +/** + Whether the error from image loader should be marked indded un-recoverable or not. + If this return YES, failed URL which does not using `SDWebImageRetryFailed` will be blocked into black list. Else not. + + @param url The URL represent the image. Note this may not be a HTTP URL + @param error The URL's loading error, from previous `requestImageWithURL:options:context:progress:completed:` completedBlock's error. + @return Whether to block this url or not. Return YES to mark this URL as failed. + */ +- (BOOL)shouldBlockFailedURLWithURL:(nonnull NSURL *)url + error:(nonnull NSError *)error; + @end diff --git a/SDWebImage/SDImageLoadersManager.m b/SDWebImage/SDImageLoadersManager.m index 91e0d941..002ef95a 100644 --- a/SDWebImage/SDImageLoadersManager.m +++ b/SDWebImage/SDImageLoadersManager.m @@ -100,4 +100,14 @@ return nil; } +- (BOOL)shouldBlockFailedURLWithURL:(NSURL *)url error:(NSError *)error { + NSArray> *loaders = self.loaders; + for (id loader in loaders.reverseObjectEnumerator) { + if ([loader canRequestImageForURL:url]) { + return [loader shouldBlockFailedURLWithURL:url error:error]; + } + } + return NO; +} + @end diff --git a/SDWebImage/SDWebImageDownloader.m b/SDWebImage/SDWebImageDownloader.m index 6ae608f9..da244659 100644 --- a/SDWebImage/SDWebImageDownloader.m +++ b/SDWebImage/SDWebImageDownloader.m @@ -546,4 +546,25 @@ didReceiveResponse:(NSURLResponse *)response return [self downloadImageWithURL:url options:downloaderOptions context:context progress:progressBlock completed:completedBlock]; } +- (BOOL)shouldBlockFailedURLWithURL:(NSURL *)url error:(NSError *)error { + BOOL shouldBlockFailedURL; + // Filter the error domain and check error codes + if ([error.domain isEqualToString:SDWebImageErrorDomain]) { + shouldBlockFailedURL = ( error.code == SDWebImageErrorInvalidURL + || error.code == SDWebImageErrorBadImageData); + } else if ([error.domain isEqualToString:NSURLErrorDomain]) { + shouldBlockFailedURL = ( error.code != NSURLErrorNotConnectedToInternet + && error.code != NSURLErrorCancelled + && error.code != NSURLErrorTimedOut + && error.code != NSURLErrorInternationalRoamingOff + && error.code != NSURLErrorDataNotAllowed + && error.code != NSURLErrorCannotFindHost + && error.code != NSURLErrorCannotConnectToHost + && error.code != NSURLErrorNetworkConnectionLost); + } else { + shouldBlockFailedURL = NO; + } + return shouldBlockFailedURL; +} + @end diff --git a/SDWebImage/SDWebImageManager.m b/SDWebImage/SDWebImageManager.m index 4d72ef0d..666148dd 100644 --- a/SDWebImage/SDWebImageManager.m +++ b/SDWebImage/SDWebImageManager.m @@ -178,7 +178,7 @@ static id _defaultImageLoader; // Query cache process - (void)callCacheProcessForOperation:(nonnull SDWebImageCombinedOperation *)operation - url:(nullable NSURL *)url + url:(nonnull NSURL *)url options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context progress:(nullable SDImageLoaderProgressBlock)progressBlock @@ -206,7 +206,7 @@ static id _defaultImageLoader; // Download process - (void)callDownloadProcessForOperation:(nonnull SDWebImageCombinedOperation *)operation - url:(nullable NSURL *)url + url:(nonnull NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context cachedImage:(nullable UIImage *)cachedImage @@ -280,7 +280,7 @@ static id _defaultImageLoader; // Store cache process - (void)callStoreCacheProcessForOperation:(nonnull SDWebImageCombinedOperation *)operation - url:(nullable NSURL *)url + url:(nonnull NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context downloadedImage:(nullable UIImage *)downloadedImage @@ -374,19 +374,7 @@ static id _defaultImageLoader; if ([self.delegate respondsToSelector:@selector(imageManager:shouldBlockFailedURL:withError:)]) { shouldBlockFailedURL = [self.delegate imageManager:self shouldBlockFailedURL:url withError:error]; } else { - // Filter the error domain and check error codes - if ([error.domain isEqualToString:NSURLErrorDomain]) { - shouldBlockFailedURL = ( error.code != NSURLErrorNotConnectedToInternet - && error.code != NSURLErrorCancelled - && error.code != NSURLErrorTimedOut - && error.code != NSURLErrorInternationalRoamingOff - && error.code != NSURLErrorDataNotAllowed - && error.code != NSURLErrorCannotFindHost - && error.code != NSURLErrorCannotConnectToHost - && error.code != NSURLErrorNetworkConnectionLost); - } else { - shouldBlockFailedURL = NO; - } + shouldBlockFailedURL = [self.imageLoader shouldBlockFailedURLWithURL:url error:error]; } return shouldBlockFailedURL; diff --git a/Tests/Tests/SDWebImageTestLoader.m b/Tests/Tests/SDWebImageTestLoader.m index 32635b2d..22978edb 100644 --- a/Tests/Tests/SDWebImageTestLoader.m +++ b/Tests/Tests/SDWebImageTestLoader.m @@ -50,4 +50,8 @@ return task; } +- (BOOL)shouldBlockFailedURLWithURL:(NSURL *)url error:(NSError *)error { + return NO; +} + @end