diff --git a/SDWebImage/SDWebImageDownloader.h b/SDWebImage/SDWebImageDownloader.h index ffc929e..1fab7e4 100644 --- a/SDWebImage/SDWebImageDownloader.h +++ b/SDWebImage/SDWebImageDownloader.h @@ -13,7 +13,8 @@ typedef enum { SDWebImageDownloaderLowPriority = 1 << 0, - SDWebImageDownloaderProgressiveDownload = 1 << 1 + SDWebImageDownloaderProgressiveDownload = 1 << 1, + SDWebImageDownloaderEnableNSURLCache = 1 << 2 } SDWebImageDownloaderOptions; typedef enum diff --git a/SDWebImage/SDWebImageDownloader.m b/SDWebImage/SDWebImageDownloader.m index 3401ee4..1dbe85a 100644 --- a/SDWebImage/SDWebImageDownloader.m +++ b/SDWebImage/SDWebImageDownloader.m @@ -120,7 +120,7 @@ static NSString *const kCompletedCallbackKey = @"completed"; [self addProgressCallback:progressBlock andCompletedBlock:completedBlock forURL:url createCallback:^ { // In order to prevent from potential duplicate caching (NSURLCache + SDImageCache) we disable the cache for image requests - NSMutableURLRequest *request = [NSMutableURLRequest.alloc initWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15]; + NSMutableURLRequest *request = [NSMutableURLRequest.alloc initWithURL:url cachePolicy:(options & SDWebImageDownloaderEnableNSURLCache ? NSURLRequestUseProtocolCachePolicy : NSURLRequestReloadIgnoringLocalCacheData) timeoutInterval:15]; request.HTTPShouldHandleCookies = NO; request.HTTPShouldUsePipelining = YES; request.allHTTPHeaderFields = wself.HTTPHeaders; diff --git a/SDWebImage/SDWebImageManager.h b/SDWebImage/SDWebImageManager.h index 84316e1..a686978 100644 --- a/SDWebImage/SDWebImageManager.h +++ b/SDWebImage/SDWebImageManager.h @@ -31,7 +31,14 @@ typedef enum * This flag enables progressive download, the image is displayed progressively during download as a browser would do. * By default, the image is only displayed once completely downloaded. */ - SDWebImageProgressiveDownload = 1 << 3 + SDWebImageProgressiveDownload = 1 << 3, + /** + * Even if the image is cached, fetch the URL again anyway. When set, NSURLCache is enabled in the downloader. + * NSURLCache will handle the protocol caching logic while SDWebImage remains useful for offline images. + * This option helps deal with images changing behind the same request URL, e.g. Facebook graph api profile pics. + * If a cached image exists, the completion block is called once with the cached image and again with the final image. + */ + SDWebImageRefreshCached = 1 << 4 } SDWebImageOptions; typedef void(^SDWebImageCompletedBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType); diff --git a/SDWebImage/SDWebImageManager.m b/SDWebImage/SDWebImageManager.m index 7a44560..5dc965d 100644 --- a/SDWebImage/SDWebImageManager.m +++ b/SDWebImage/SDWebImageManager.m @@ -97,16 +97,21 @@ if (image) { completedBlock(image, nil, cacheType, YES); - @synchronized(self.runningOperations) - { - [self.runningOperations removeObject:operation]; + if (!(options & SDWebImageRefreshCached)) { + @synchronized(self.runningOperations) + { + [self.runningOperations removeObject:operation]; + } } } - else if (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url]) + + if ((!image || options & SDWebImageRefreshCached) && (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url])) { + // download if no image or requested to refresh anyway, and download allowed by delegate SDWebImageDownloaderOptions downloaderOptions = 0; if (options & SDWebImageLowPriority) downloaderOptions |= SDWebImageDownloaderLowPriority; if (options & SDWebImageProgressiveDownload) downloaderOptions |= SDWebImageDownloaderProgressiveDownload; + if (options & SDWebImageRefreshCached) downloaderOptions |= SDWebImageDownloaderEnableNSURLCache; __block id subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(UIImage *downloadedImage, NSData *data, NSError *error, BOOL finished) { if (weakOperation.cancelled) @@ -167,7 +172,7 @@ }]; operation.cancelBlock = ^{[subOperation cancel];}; } - else + else if (!image) { // Image not in cache and download disallowed by delegate completedBlock(nil, nil, SDImageCacheTypeNone, YES);