Add `SDWebImageManager` delegate allowing fine control of manager's cache-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)
This commit is contained in:
parent
6f198abd1b
commit
ebd63a88c1
|
@ -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;
|
||||
|
||||
|
|
|
@ -101,17 +101,17 @@
|
|||
[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 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
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 @@
|
|||
}];
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue