diff --git a/SDWebImage/SDImageLoader.h b/SDWebImage/SDImageLoader.h index a69f7c53..f4de58fa 100644 --- a/SDWebImage/SDImageLoader.h +++ b/SDWebImage/SDImageLoader.h @@ -85,4 +85,18 @@ FOUNDATION_EXPORT UIImage * _Nullable SDImageLoaderDecodeProgressiveImageData(NS progress:(nullable SDImageLoaderProgressBlock)progressBlock completed:(nullable SDImageLoaderCompletedBlock)completedBlock; + +@optional +/** + 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. + If does not implements this method, assume always return NO. + + @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..dd99c31c 100644 --- a/SDWebImage/SDImageLoadersManager.m +++ b/SDWebImage/SDImageLoadersManager.m @@ -100,4 +100,17 @@ return nil; } +- (BOOL)shouldBlockFailedURLWithURL:(NSURL *)url error:(NSError *)error { + NSArray> *loaders = self.loaders; + for (id loader in loaders.reverseObjectEnumerator) { + if (![loader respondsToSelector:@selector(shouldBlockFailedURLWithURL:error:)]) { + break; + } + 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 409b07ab..2ffe6c61 100644 --- a/SDWebImage/SDWebImageManager.m +++ b/SDWebImage/SDWebImageManager.m @@ -374,19 +374,8 @@ 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: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); + if ([self.imageLoader respondsToSelector:@selector(shouldBlockFailedURLWithURL:error:)]) { + shouldBlockFailedURL = [self.imageLoader shouldBlockFailedURLWithURL:url error:error]; } else { shouldBlockFailedURL = NO; }