Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add `SDWebImageManager` delegate allowing fine control of manager's c…

…ache-in

- `imageManager:shouldDownloadImageForURL:` let delegate to conditionaly block cache-in (fix #134)
- `imageManager:transformDownloadedImage:` let delegate to transform the image prior to cache-in (fix #63, fix #284)
  • Loading branch information...
commit ebd63a88c116ac7acfbeded5c84d0fffa2443438 1 parent 6f198ab
Olivier Poitrey authored
Showing with 72 additions and 5 deletions.
  1. +32 −0 SDWebImage/SDWebImageManager.h
  2. +40 −5 SDWebImage/SDWebImageManager.m
32 SDWebImage/SDWebImageManager.h
View
@@ -38,6 +38,36 @@ typedef void(^SDWebImageCompletedBlock)(UIImage *image, NSError *error, SDImageC
typedef void(^SDWebImageCompletedWithFinishedBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished);
+@class SDWebImageManager;
+
+@protocol SDWebImageManagerDelegate <NSObject>
+
+@optional
+
+/**
+ * Controls which image should be downloaded when the image is not found in the cache.
+ *
+ * @param imageManager The current `SDWebImageManager`
+ * @param imageURL The url of the image to be downloaded
+ *
+ * @return Return NO to prevent the downloading of the image on cache misses. If not implemented, YES is implied.
+ */
+- (BOOL)imageManager:(SDWebImageManager *)imageManager shouldDownloadImageForURL:(NSURL *)imageURL;
+
+/**
+ * Allows to transform the image immediately after it has been downloaded and just before to cache it on disk and memory.
+ * NOTE: This method is called from a global queue in order to not to block the main thread.
+ *
+ * @param imageManager The current `SDWebImageManager`
+ * @param image The image to transform
+ * @param imageURL The url of the image to transform
+ *
+ * @return The transformed image object.
+ */
+- (UIImage *)imageManager:(SDWebImageManager *)imageManager transformDownloadedImage:(UIImage *)image withURL:(NSURL *)imageURL;
+
+@end
+
/**
* The SDWebImageManager is the class behind the UIImageView+WebCache category and likes.
* It ties the asynchronous downloader (SDWebImageDownloader) with the image cache store (SDImageCache).
@@ -61,6 +91,8 @@ typedef void(^SDWebImageCompletedWithFinishedBlock)(UIImage *image, NSError *err
*/
@interface SDWebImageManager : NSObject
+@property (weak, nonatomic) id<SDWebImageManagerDelegate> delegate;
+
@property (strong, nonatomic, readonly) SDImageCache *imageCache;
@property (strong, nonatomic, readonly) SDWebImageDownloader *imageDownloader;
45 SDWebImage/SDWebImageManager.m
View
@@ -101,17 +101,17 @@ - (NSString *)cacheKeyForURL:(NSURL *)url
[self.runningOperations removeObject:operation];
}
}
- else
+ else if (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url])
{
SDWebImageDownloaderOptions downloaderOptions = 0;
if (options & SDWebImageLowPriority) downloaderOptions |= SDWebImageDownloaderLowPriority;
if (options & SDWebImageProgressiveDownload) downloaderOptions |= SDWebImageDownloaderProgressiveDownload;
__block id<SDWebImageOperation> subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(UIImage *downloadedImage, NSData *data, NSError *error, BOOL finished)
{
- completedBlock(downloadedImage, error, SDImageCacheTypeNone, finished);
-
if (error)
{
+ completedBlock(nil, error, SDImageCacheTypeNone, finished);
+
if (error.code != NSURLErrorNotConnectedToInternet)
{
@synchronized(self.failedURLs)
@@ -120,10 +120,36 @@ - (NSString *)cacheKeyForURL:(NSURL *)url
}
}
}
- else if (downloadedImage && finished)
+ else
{
const BOOL cacheOnDisk = !(options & SDWebImageCacheMemoryOnly);
- [self.imageCache storeImage:downloadedImage imageData:data forKey:key toDisk:cacheOnDisk];
+
+ if (downloadedImage && [self.delegate respondsToSelector:@selector(imageManager:transformDownloadedImage:withURL:)])
+ {
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^
+ {
+ UIImage *transformedImage = [self.delegate imageManager:self transformDownloadedImage:downloadedImage withURL:url];
+
+ dispatch_async(dispatch_get_main_queue(), ^
+ {
+ completedBlock(transformedImage, nil, SDImageCacheTypeNone, finished);
+ });
+
+ if (transformedImage && finished)
+ {
+ [self.imageCache storeImage:transformedImage imageData:data forKey:key toDisk:cacheOnDisk];
+ }
+ });
+ }
+ else
+ {
+ completedBlock(downloadedImage, nil, SDImageCacheTypeNone, finished);
+
+ if (downloadedImage && finished)
+ {
+ [self.imageCache storeImage:downloadedImage imageData:data forKey:key toDisk:cacheOnDisk];
+ }
+ }
}
if (finished)
@@ -136,6 +162,15 @@ - (NSString *)cacheKeyForURL:(NSURL *)url
}];
operation.cancelBlock = ^{[subOperation cancel];};
}
+ else
+ {
+ // Image not in cache and download disallowed by delegate
+ completedBlock(nil, nil, SDImageCacheTypeNone, YES);
+ @synchronized(self.runningOperations)
+ {
+ [self.runningOperations removeObject:operation];
+ }
+ }
}];
return operation;

1 comment on commit ebd63a8

Alexander

if (transformedImage && finished)
{
[self.imageCache storeImage:transformedImage imageData:data forKey:key toDisk:cacheOnDisk];
}

wrong imageData value passed here - input parameter data was imageData for downloaded image ..its not data for transformedImage
u should pass nil here [self.imageCache storeImage:transformedImage imageData:nil forKey:key toDisk:cacheOnDisk];

Please sign in to comment.
Something went wrong with that request. Please try again.