提交图片下载失败,走下发IP直连重试功能 review 小熊
Showing
5 changed files
with
69 additions
and
15 deletions
@@ -68,15 +68,24 @@ extern NSString *const SDWebImageDownloadStopNotification; | @@ -68,15 +68,24 @@ extern NSString *const SDWebImageDownloadStopNotification; | ||
68 | 68 | ||
69 | typedef void(^SDWebImageDownloaderProgressBlock)(NSInteger receivedSize, NSInteger expectedSize); | 69 | typedef void(^SDWebImageDownloaderProgressBlock)(NSInteger receivedSize, NSInteger expectedSize); |
70 | 70 | ||
71 | -typedef void(^SDWebImageDownloaderCompletedBlock)(UIImage *image, NSData *data, NSError *error, BOOL finished); | 71 | +typedef void(^SDWebImageDownloaderCompletedBlock)(NSURLRequest *request,UIImage *image, NSData *data, NSError *error, BOOL finished); |
72 | 72 | ||
73 | typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDictionary *headers); | 73 | typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDictionary *headers); |
74 | 74 | ||
75 | +@protocol SDWebImageDownloaderDelegate <NSObject> | ||
76 | + | ||
77 | +@optional | ||
78 | +/** | ||
79 | + * 走图片下载直连ip请求时设置超时时间为5s. | ||
80 | + */ | ||
81 | +- (NSTimeInterval)setDirectIpRetryTimeout:(NSString *)host; | ||
82 | +@end | ||
75 | /** | 83 | /** |
76 | * Asynchronous downloader dedicated and optimized for image loading. | 84 | * Asynchronous downloader dedicated and optimized for image loading. |
77 | */ | 85 | */ |
78 | @interface SDWebImageDownloader : NSObject | 86 | @interface SDWebImageDownloader : NSObject |
79 | 87 | ||
88 | +@property (weak, nonatomic) id <SDWebImageDownloaderDelegate> delegate; | ||
80 | /** | 89 | /** |
81 | * Decompressing images that are downloaded and cached can improve peformance but can consume lot of memory. | 90 | * Decompressing images that are downloaded and cached can improve peformance but can consume lot of memory. |
82 | * Defaults to YES. Set this to NO if you are experiencing a crash due to excessive memory consumption. | 91 | * Defaults to YES. Set this to NO if you are experiencing a crash due to excessive memory consumption. |
@@ -118,6 +118,11 @@ static NSString *const kCompletedCallbackKey = @"completed"; | @@ -118,6 +118,11 @@ static NSString *const kCompletedCallbackKey = @"completed"; | ||
118 | 118 | ||
119 | [self addProgressCallback:progressBlock andCompletedBlock:completedBlock forURL:url createCallback:^{ | 119 | [self addProgressCallback:progressBlock andCompletedBlock:completedBlock forURL:url createCallback:^{ |
120 | NSTimeInterval timeoutInterval = wself.downloadTimeout; | 120 | NSTimeInterval timeoutInterval = wself.downloadTimeout; |
121 | + | ||
122 | + if ([self.delegate respondsToSelector:@selector(setDirectIpRetryTimeout:)]) { | ||
123 | + timeoutInterval = [self.delegate setDirectIpRetryTimeout:url.host]; | ||
124 | + } | ||
125 | + | ||
121 | if (timeoutInterval == 0.0) { | 126 | if (timeoutInterval == 0.0) { |
122 | timeoutInterval = 15.0; | 127 | timeoutInterval = 15.0; |
123 | } | 128 | } |
@@ -146,9 +151,10 @@ static NSString *const kCompletedCallbackKey = @"completed"; | @@ -146,9 +151,10 @@ static NSString *const kCompletedCallbackKey = @"completed"; | ||
146 | if (callback) callback(receivedSize, expectedSize); | 151 | if (callback) callback(receivedSize, expectedSize); |
147 | } | 152 | } |
148 | } | 153 | } |
149 | - completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) { | 154 | + completed:^(NSURLRequest *requestx,UIImage *image, NSData *data, NSError *error, BOOL finished) { |
150 | SDWebImageDownloader *sself = wself; | 155 | SDWebImageDownloader *sself = wself; |
151 | if (!sself) return; | 156 | if (!sself) return; |
157 | + | ||
152 | __block NSArray *callbacksForURL; | 158 | __block NSArray *callbacksForURL; |
153 | dispatch_barrier_sync(sself.barrierQueue, ^{ | 159 | dispatch_barrier_sync(sself.barrierQueue, ^{ |
154 | callbacksForURL = [sself.URLCallbacks[url] copy]; | 160 | callbacksForURL = [sself.URLCallbacks[url] copy]; |
@@ -158,12 +164,13 @@ static NSString *const kCompletedCallbackKey = @"completed"; | @@ -158,12 +164,13 @@ static NSString *const kCompletedCallbackKey = @"completed"; | ||
158 | }); | 164 | }); |
159 | for (NSDictionary *callbacks in callbacksForURL) { | 165 | for (NSDictionary *callbacks in callbacksForURL) { |
160 | SDWebImageDownloaderCompletedBlock callback = callbacks[kCompletedCallbackKey]; | 166 | SDWebImageDownloaderCompletedBlock callback = callbacks[kCompletedCallbackKey]; |
161 | - if (callback) callback(image, data, error, finished); | 167 | + if (callback) callback(requestx, image, data, error, finished); |
162 | } | 168 | } |
163 | } | 169 | } |
164 | cancelled:^{ | 170 | cancelled:^{ |
165 | SDWebImageDownloader *sself = wself; | 171 | SDWebImageDownloader *sself = wself; |
166 | if (!sself) return; | 172 | if (!sself) return; |
173 | + | ||
167 | dispatch_barrier_async(sself.barrierQueue, ^{ | 174 | dispatch_barrier_async(sself.barrierQueue, ^{ |
168 | [sself.URLCallbacks removeObjectForKey:url]; | 175 | [sself.URLCallbacks removeObjectForKey:url]; |
169 | }); | 176 | }); |
@@ -195,7 +202,7 @@ static NSString *const kCompletedCallbackKey = @"completed"; | @@ -195,7 +202,7 @@ static NSString *const kCompletedCallbackKey = @"completed"; | ||
195 | // The URL will be used as the key to the callbacks dictionary so it cannot be nil. If it is nil immediately call the completed block with no image or data. | 202 | // The URL will be used as the key to the callbacks dictionary so it cannot be nil. If it is nil immediately call the completed block with no image or data. |
196 | if (url == nil) { | 203 | if (url == nil) { |
197 | if (completedBlock != nil) { | 204 | if (completedBlock != nil) { |
198 | - completedBlock(nil, nil, nil, NO); | 205 | + completedBlock(nil,nil, nil, nil, NO); |
199 | } | 206 | } |
200 | return; | 207 | return; |
201 | } | 208 | } |
@@ -125,7 +125,7 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis | @@ -125,7 +125,7 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis | ||
125 | } | 125 | } |
126 | else { | 126 | else { |
127 | if (self.completedBlock) { | 127 | if (self.completedBlock) { |
128 | - self.completedBlock(nil, nil, [NSError errorWithDomain:NSURLErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Connection can't be initialized"}], YES); | 128 | + self.completedBlock(nil, nil, nil, [NSError errorWithDomain:NSURLErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Connection can't be initialized"}], YES); |
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
@@ -264,7 +264,7 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis | @@ -264,7 +264,7 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis | ||
264 | }); | 264 | }); |
265 | 265 | ||
266 | if (self.completedBlock) { | 266 | if (self.completedBlock) { |
267 | - self.completedBlock(nil, nil, [NSError errorWithDomain:NSURLErrorDomain code:[((NSHTTPURLResponse *)response) statusCode] userInfo:nil], YES); | 267 | + self.completedBlock(nil, nil, nil, [NSError errorWithDomain:NSURLErrorDomain code:[((NSHTTPURLResponse *)response) statusCode] userInfo:nil], YES); |
268 | } | 268 | } |
269 | CFRunLoopStop(CFRunLoopGetCurrent()); | 269 | CFRunLoopStop(CFRunLoopGetCurrent()); |
270 | [self done]; | 270 | [self done]; |
@@ -342,7 +342,7 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis | @@ -342,7 +342,7 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis | ||
342 | CGImageRelease(partialImageRef); | 342 | CGImageRelease(partialImageRef); |
343 | dispatch_main_sync_safe(^{ | 343 | dispatch_main_sync_safe(^{ |
344 | if (self.completedBlock) { | 344 | if (self.completedBlock) { |
345 | - self.completedBlock(image, nil, nil, NO); | 345 | + self.completedBlock(nil, image, nil, nil, NO); |
346 | } | 346 | } |
347 | }); | 347 | }); |
348 | } | 348 | } |
@@ -401,7 +401,7 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis | @@ -401,7 +401,7 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis | ||
401 | 401 | ||
402 | if (completionBlock) { | 402 | if (completionBlock) { |
403 | if (self.options & SDWebImageDownloaderIgnoreCachedResponse && responseFromCached) { | 403 | if (self.options & SDWebImageDownloaderIgnoreCachedResponse && responseFromCached) { |
404 | - completionBlock(nil, nil, nil, YES); | 404 | + completionBlock(nil, nil, nil, nil, YES); |
405 | } else if (self.imageData) { | 405 | } else if (self.imageData) { |
406 | UIImage *image = [UIImage sd_imageWithData:self.imageData]; | 406 | UIImage *image = [UIImage sd_imageWithData:self.imageData]; |
407 | NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:self.request.URL]; | 407 | NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:self.request.URL]; |
@@ -414,13 +414,13 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis | @@ -414,13 +414,13 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis | ||
414 | } | 414 | } |
415 | } | 415 | } |
416 | if (CGSizeEqualToSize(image.size, CGSizeZero)) { | 416 | if (CGSizeEqualToSize(image.size, CGSizeZero)) { |
417 | - completionBlock(nil, nil, [NSError errorWithDomain:SDWebImageErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Downloaded image has 0 pixels"}], YES); | 417 | + completionBlock(nil, nil, nil, [NSError errorWithDomain:SDWebImageErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Downloaded image has 0 pixels"}], YES); |
418 | } | 418 | } |
419 | else { | 419 | else { |
420 | - completionBlock(image, self.imageData, nil, YES); | 420 | + completionBlock(self.request, image, self.imageData, nil, YES); |
421 | } | 421 | } |
422 | } else { | 422 | } else { |
423 | - completionBlock(nil, nil, [NSError errorWithDomain:SDWebImageErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Image data is nil"}], YES); | 423 | + completionBlock(nil, nil, nil, [NSError errorWithDomain:SDWebImageErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Image data is nil"}], YES); |
424 | } | 424 | } |
425 | } | 425 | } |
426 | self.completionBlock = nil; | 426 | self.completionBlock = nil; |
@@ -439,7 +439,7 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis | @@ -439,7 +439,7 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis | ||
439 | } | 439 | } |
440 | 440 | ||
441 | if (self.completedBlock) { | 441 | if (self.completedBlock) { |
442 | - self.completedBlock(nil, nil, error, YES); | 442 | + self.completedBlock(nil, nil, nil, error, YES); |
443 | } | 443 | } |
444 | self.completionBlock = nil; | 444 | self.completionBlock = nil; |
445 | [self done]; | 445 | [self done]; |
@@ -113,8 +113,31 @@ typedef NSString *(^SDWebImageCacheKeyFilterBlock)(NSURL *url); | @@ -113,8 +113,31 @@ typedef NSString *(^SDWebImageCacheKeyFilterBlock)(NSURL *url); | ||
113 | * @return Return NO to prevent the downloading of the image on cache misses. If not implemented, YES is implied. | 113 | * @return Return NO to prevent the downloading of the image on cache misses. If not implemented, YES is implied. |
114 | */ | 114 | */ |
115 | - (BOOL)imageManager:(SDWebImageManager *)imageManager shouldDownloadImageForURL:(NSURL *)imageURL; | 115 | - (BOOL)imageManager:(SDWebImageManager *)imageManager shouldDownloadImageForURL:(NSURL *)imageURL; |
116 | +/** | ||
117 | + * If download image from original url failed,app use img_ip retry again | ||
118 | + * | ||
119 | + * @param imageManager The current `SDWebImageManager` | ||
120 | + * @param imageURL The url of the image to be downloaded | ||
121 | + * @param options SDWebImageOptions | ||
122 | +* @param progressBlock progressBlock | ||
123 | +* @param completedBlock completedBlock | ||
124 | + * @return NONE. | ||
125 | + */ | ||
126 | +- (void)imageManager:(SDWebImageManager *)imageManager didFailedDownloadImageWithURL:(NSURL *)imageURL | ||
127 | + options:(SDWebImageOptions)options | ||
128 | + progress:(SDWebImageDownloaderProgressBlock)progressBlock | ||
129 | + completed:(SDWebImageCompletionWithFinishedBlock)completedBlock; | ||
116 | 130 | ||
117 | /** | 131 | /** |
132 | + * Controls which image should be downloaded when the image is not found in the cache. | ||
133 | + * | ||
134 | + * @param imageManager The current `SDWebImageManager` | ||
135 | + * @param imageURL The url of the image to be downloaded | ||
136 | + * | ||
137 | + * @return Return original url | ||
138 | + */ | ||
139 | +- (NSString *)imageManager:(SDWebImageManager *)imageManager didSuccessedWithRequest:(NSURLRequest *)request cacheKey:(NSString *)key; | ||
140 | +/** | ||
118 | * Allows to transform the image immediately after it has been downloaded and just before to cache it on disk and memory. | 141 | * Allows to transform the image immediately after it has been downloaded and just before to cache it on disk and memory. |
119 | * NOTE: This method is called from a global queue in order to not to block the main thread. | 142 | * NOTE: This method is called from a global queue in order to not to block the main thread. |
120 | * | 143 | * |
@@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
8 | 8 | ||
9 | #import "SDWebImageManager.h" | 9 | #import "SDWebImageManager.h" |
10 | #import <objc/message.h> | 10 | #import <objc/message.h> |
11 | +#import "SDWebImageDownloaderOperation.h" | ||
11 | 12 | ||
12 | @interface SDWebImageCombinedOperation : NSObject <SDWebImageOperation> | 13 | @interface SDWebImageCombinedOperation : NSObject <SDWebImageOperation> |
13 | 14 | ||
@@ -144,7 +145,7 @@ | @@ -144,7 +145,7 @@ | ||
144 | @synchronized (self.runningOperations) { | 145 | @synchronized (self.runningOperations) { |
145 | [self.runningOperations addObject:operation]; | 146 | [self.runningOperations addObject:operation]; |
146 | } | 147 | } |
147 | - NSString *key = [self cacheKeyForURL:url]; | 148 | + __block NSString *key = [self cacheKeyForURL:url]; |
148 | 149 | ||
149 | operation.cacheOperation = [self.imageCache queryDiskCacheForKey:key done:^(UIImage *image, SDImageCacheType cacheType) { | 150 | operation.cacheOperation = [self.imageCache queryDiskCacheForKey:key done:^(UIImage *image, SDImageCacheType cacheType) { |
150 | if (operation.isCancelled) { | 151 | if (operation.isCancelled) { |
@@ -179,7 +180,8 @@ | @@ -179,7 +180,8 @@ | ||
179 | // ignore image read from NSURLCache if image if cached but force refreshing | 180 | // ignore image read from NSURLCache if image if cached but force refreshing |
180 | downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse; | 181 | downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse; |
181 | } | 182 | } |
182 | - id <SDWebImageOperation> subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(UIImage *downloadedImage, NSData *data, NSError *error, BOOL finished) { | 183 | + id <SDWebImageOperation> subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(NSURLRequest *request,UIImage *downloadedImage, NSData *data, NSError *error, BOOL finished) { |
184 | + | ||
183 | if (weakOperation.isCancelled) { | 185 | if (weakOperation.isCancelled) { |
184 | // Do nothing if the operation was cancelled | 186 | // Do nothing if the operation was cancelled |
185 | // See #699 for more details | 187 | // See #699 for more details |
@@ -188,19 +190,32 @@ | @@ -188,19 +190,32 @@ | ||
188 | else if (error) { | 190 | else if (error) { |
189 | dispatch_main_sync_safe(^{ | 191 | dispatch_main_sync_safe(^{ |
190 | if (!weakOperation.isCancelled) { | 192 | if (!weakOperation.isCancelled) { |
191 | - completedBlock(nil, error, SDImageCacheTypeNone, finished, url); | 193 | + completedBlock( nil, error, SDImageCacheTypeNone, finished, url); |
192 | } | 194 | } |
193 | }); | 195 | }); |
194 | 196 | ||
195 | BOOL shouldBeFailedURLAlliOSVersion = (error.code != NSURLErrorNotConnectedToInternet && error.code != NSURLErrorCancelled && error.code != NSURLErrorTimedOut); | 197 | BOOL shouldBeFailedURLAlliOSVersion = (error.code != NSURLErrorNotConnectedToInternet && error.code != NSURLErrorCancelled && error.code != NSURLErrorTimedOut); |
196 | BOOL shouldBeFailedURLiOS7 = (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1 && error.code != NSURLErrorInternationalRoamingOff && error.code != NSURLErrorCallIsActive && error.code != NSURLErrorDataNotAllowed); | 198 | BOOL shouldBeFailedURLiOS7 = (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1 && error.code != NSURLErrorInternationalRoamingOff && error.code != NSURLErrorCallIsActive && error.code != NSURLErrorDataNotAllowed); |
197 | if (shouldBeFailedURLAlliOSVersion || shouldBeFailedURLiOS7) { | 199 | if (shouldBeFailedURLAlliOSVersion || shouldBeFailedURLiOS7) { |
200 | + | ||
201 | + if ([self.delegate respondsToSelector:@selector(imageManager:didFailedDownloadImageWithURL:options:progress:completed:)]) { | ||
202 | + [self.delegate imageManager:self didFailedDownloadImageWithURL:url options:options progress:progressBlock completed:completedBlock]; | ||
203 | + } | ||
204 | + | ||
198 | @synchronized (self.failedURLs) { | 205 | @synchronized (self.failedURLs) { |
199 | [self.failedURLs addObject:url]; | 206 | [self.failedURLs addObject:url]; |
200 | } | 207 | } |
201 | } | 208 | } |
202 | } | 209 | } |
203 | else { | 210 | else { |
211 | + | ||
212 | + if ([self.delegate respondsToSelector:@selector(imageManager:didSuccessedWithRequest:cacheKey:)]){ | ||
213 | + NSString * originalUrl = [self.delegate imageManager:self didSuccessedWithRequest:request cacheKey:key]; | ||
214 | + if (originalUrl.length > 0) { | ||
215 | + key = originalUrl; | ||
216 | + } | ||
217 | + } | ||
218 | + | ||
204 | if ((options & SDWebImageRetryFailed)) { | 219 | if ((options & SDWebImageRetryFailed)) { |
205 | @synchronized (self.failedURLs) { | 220 | @synchronized (self.failedURLs) { |
206 | [self.failedURLs removeObject:url]; | 221 | [self.failedURLs removeObject:url]; |
-
Please register or login to post a comment