From 6781045698690a3f557520dff334c7d262ab2bc8 Mon Sep 17 00:00:00 2001 From: Olivier Poitrey Date: Sat, 10 Mar 2012 20:15:06 +0100 Subject: [PATCH] Add some backward compatible block support (fix #64) --- README.md | 14 ++++++++++ SDWebImageManager.h | 3 +++ SDWebImageManager.m | 48 ++++++++++++++++++++++++++++++++++ UIButton+WebCache.h | 58 +++++++++++++++++++++++++++++++++++++++--- UIButton+WebCache.m | 34 ++++++++++++++++++++++++- UIImageView+WebCache.h | 51 ++++++++++++++++++++++++++++++++----- UIImageView+WebCache.m | 27 ++++++++++++++++++++ 7 files changed, 223 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index aef7cc2..41329d5 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,20 @@ handled for you, from async downloads to caching management. return cell; } +### Using blocks + +If your project's deployement target is set to iOS 4+, you may want to use the success/failure blocks to be +notified when image have been retrieved from cache. + + // Here we use the new provided setImageWithURL: method to load the web image + [cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] + placeholderImage:[UIImage imageNamed:@"placeholder.png"] + success:^(UIImage *image) {... success code here ...} + failure:^(NSError *error) {... failure code here ...}]; +]; + +Note: neither your success nor failure block will be call if your image request is canceled before completion. + ### Using SDWebImageManager The SDWebImageManager is the class behind the UIImageView+WebCache category. It ties the diff --git a/SDWebImageManager.h b/SDWebImageManager.h index aef63ca..e14f632 100644 --- a/SDWebImageManager.h +++ b/SDWebImageManager.h @@ -34,6 +34,9 @@ typedef enum - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate options:(SDWebImageOptions)options; - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate retryFailed:(BOOL)retryFailed __attribute__ ((deprecated)); // use options:SDWebImageRetryFailed instead - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate retryFailed:(BOOL)retryFailed lowPriority:(BOOL)lowPriority __attribute__ ((deprecated)); // use options:SDWebImageRetryFailed|SDWebImageLowPriority instead +#if NS_BLOCKS_AVAILABLE +- (void)downloadWithURL:(NSURL *)url delegate:(id)delegate options:(SDWebImageOptions)options success:(void (^)(UIImage *image))success failure:(void (^)(NSError *error))failure; +#endif - (void)cancelForDelegate:(id)delegate; @end diff --git a/SDWebImageManager.m b/SDWebImageManager.m index 8f9c9ad..39ca1d4 100644 --- a/SDWebImageManager.m +++ b/SDWebImageManager.m @@ -11,10 +11,25 @@ #import "SDWebImageDownloader.h" #import +#if NS_BLOCKS_AVAILABLE +typedef void(^SuccessBlock)(UIImage *image); +typedef void(^FailureBlock)(NSError *error); + +@interface SDWebImageManager () +@property (nonatomic, copy) SuccessBlock successBlock; +@property (nonatomic, copy) FailureBlock failureBlock; +@end +#endif + static SDWebImageManager *instance; @implementation SDWebImageManager +#if NS_BLOCKS_AVAILABLE +@synthesize successBlock; +@synthesize failureBlock; +#endif + - (id)init { if ((self = [super init])) @@ -107,6 +122,15 @@ static SDWebImageManager *instance; [[SDImageCache sharedImageCache] queryDiskCacheForKey:[url absoluteString] delegate:self userInfo:info]; } +#if NS_BLOCKS_AVAILABLE +- (void)downloadWithURL:(NSURL *)url delegate:(id)delegate options:(SDWebImageOptions)options success:(void (^)(UIImage *image))success failure:(void (^)(NSError *error))failure +{ + self.successBlock = success; + self.failureBlock = failure; + [self downloadWithURL:url delegate:delegate options:options]; +} +#endif + - (void)cancelForDelegate:(id)delegate { NSUInteger idx; @@ -170,6 +194,12 @@ static SDWebImageManager *instance; { objc_msgSend(delegate, @selector(webImageManager:didFinishWithImage:forURL:), self, image, url); } +#if NS_BLOCKS_AVAILABLE + if (self.successBlock) + { + self.successBlock(image); + } +#endif [cacheDelegates removeObjectAtIndex:idx]; [cacheURLs removeObjectAtIndex:idx]; @@ -238,6 +268,12 @@ static SDWebImageManager *instance; { objc_msgSend(delegate, @selector(webImageManager:didFinishWithImage:forURL:), self, image, downloader.url); } +#if NS_BLOCKS_AVAILABLE + if (self.successBlock) + { + self.successBlock(image); + } +#endif } else { @@ -249,6 +285,12 @@ static SDWebImageManager *instance; { objc_msgSend(delegate, @selector(webImageManager:didFailWithError:forURL:), self, nil, downloader.url); } +#if NS_BLOCKS_AVAILABLE + if (self.failureBlock) + { + self.failureBlock(nil); + } +#endif } [downloaders removeObjectAtIndex:uidx]; @@ -300,6 +342,12 @@ static SDWebImageManager *instance; { objc_msgSend(delegate, @selector(webImageManager:didFailWithError:forURL:), self, error, downloader.url); } +#if NS_BLOCKS_AVAILABLE + if (self.failureBlock) + { + self.failureBlock(error); + } +#endif [downloaders removeObjectAtIndex:uidx]; [downloadDelegates removeObjectAtIndex:uidx]; diff --git a/UIButton+WebCache.h b/UIButton+WebCache.h index f373066..d0683de 100644 --- a/UIButton+WebCache.h +++ b/UIButton+WebCache.h @@ -8,6 +8,7 @@ #import "SDWebImageCompat.h" #import "SDWebImageManagerDelegate.h" +#import "SDWebImageManager.h" @interface UIButton (WebCache) @@ -16,8 +17,7 @@ * * The downloand is asynchronous and cached. * - * @param url The url that the image is found. - * @see setImageWithURL:placeholderImage: + * @param url The url for the image. */ - (void)setImageWithURL:(NSURL *)url; @@ -26,11 +26,61 @@ * * The downloand is asynchronous and cached. * - * @param url The url that the `image` is found. - * @param placeholder A `image` that will be visible while loading the final image. + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @see setImageWithURL:placeholderImage:options: */ - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; +/** + * Set the imageView `image` with an `url`, placeholder and custom options. + * + * The downloand is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + */ +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; + +#if NS_BLOCKS_AVAILABLE +/** + * Set the imageView `image` with an `url`. + * + * The downloand is asynchronous and cached. + * + * @param url The url for the image. + * @param success A block to be executed when the image request succeed This block has no return value and takes the retrieved image as argument. + * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). + */ +- (void)setImageWithURL:(NSURL *)url success:(void (^)(UIImage *image))success failure:(void (^)(NSError *error))failure; + +/** + * Set the imageView `image` with an `url`, placeholder. + * + * The downloand is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param success A block to be executed when the image request succeed This block has no return value and takes the retrieved image as argument. + * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). + */ +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder success:(void (^)(UIImage *image))success failure:(void (^)(NSError *error))failure; + +/** + * Set the imageView `image` with an `url`, placeholder and custom options. + * + * The downloand is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param success A block to be executed when the image request succeed This block has no return value and takes the retrieved image as argument. + * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). + */ +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options success:(void (^)(UIImage *image))success failure:(void (^)(NSError *error))failure; +#endif + /** * Cancel the current download */ diff --git a/UIButton+WebCache.m b/UIButton+WebCache.m index ba7f9ac..e7ac2ac 100644 --- a/UIButton+WebCache.m +++ b/UIButton+WebCache.m @@ -17,6 +17,11 @@ } - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder +{ + [self setImageWithURL:url placeholderImage:nil options:0]; +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { SDWebImageManager *manager = [SDWebImageManager sharedManager]; @@ -27,10 +32,37 @@ if (url) { - [manager downloadWithURL:url delegate:self]; + [manager downloadWithURL:url delegate:self options:options]; } } +#if NS_BLOCKS_AVAILABLE +- (void)setImageWithURL:(NSURL *)url success:(void (^)(UIImage *image))success failure:(void (^)(NSError *error))failure; +{ + [self setImageWithURL:url placeholderImage:nil success:success failure:failure]; +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder success:(void (^)(UIImage *image))success failure:(void (^)(NSError *error))failure; +{ + [self setImageWithURL:url placeholderImage:placeholder options:0 success:success failure:failure]; +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options success:(void (^)(UIImage *image))success failure:(void (^)(NSError *error))failure; +{ + SDWebImageManager *manager = [SDWebImageManager sharedManager]; + + // Remove in progress downloader from queue + [manager cancelForDelegate:self]; + + [self setImage:placeholder forState:UIControlStateNormal]; + + if (url) + { + [manager downloadWithURL:url delegate:self options:options success:success failure:failure]; + } +} +#endif + - (void)cancelCurrentImageLoad { [[SDWebImageManager sharedManager] cancelForDelegate:self]; diff --git a/UIImageView+WebCache.h b/UIImageView+WebCache.h index 7ee3517..d519785 100644 --- a/UIImageView+WebCache.h +++ b/UIImageView+WebCache.h @@ -17,8 +17,7 @@ * * The downloand is asynchronous and cached. * - * @param url The url that the image is found. - * @see setImageWithURL:placeholderImage: + * @param url The url for the image. */ - (void)setImageWithURL:(NSURL *)url; @@ -27,8 +26,8 @@ * * The downloand is asynchronous and cached. * - * @param url The url that the `image` is found. - * @param placeholder A `image` that will be visible while loading the final image. + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. * @see setImageWithURL:placeholderImage:options: */ - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; @@ -38,12 +37,50 @@ * * The downloand is asynchronous and cached. * - * @param url The url that the `image` is found. - * @param placeholder A `image` that will be visible while loading the final image. - * @param options A list of `SDWebImageOptions` for current `imageView`. Available options are `SDWebImageRetryFailed`, `SDWebImageLowPriority` and `SDWebImageCacheMemoryOnly`. + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. */ - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; +#if NS_BLOCKS_AVAILABLE +/** + * Set the imageView `image` with an `url`. + * + * The downloand is asynchronous and cached. + * + * @param url The url for the image. + * @param success A block to be executed when the image request succeed This block has no return value and takes the retrieved image as argument. + * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). + */ +- (void)setImageWithURL:(NSURL *)url success:(void (^)(UIImage *image))success failure:(void (^)(NSError *error))failure; + +/** + * Set the imageView `image` with an `url`, placeholder. + * + * The downloand is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param success A block to be executed when the image request succeed This block has no return value and takes the retrieved image as argument. + * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). + */ +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder success:(void (^)(UIImage *image))success failure:(void (^)(NSError *error))failure; + +/** + * Set the imageView `image` with an `url`, placeholder and custom options. + * + * The downloand is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param success A block to be executed when the image request succeed This block has no return value and takes the retrieved image as argument. + * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). + */ +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options success:(void (^)(UIImage *image))success failure:(void (^)(NSError *error))failure; +#endif + /** * Cancel the current download */ diff --git a/UIImageView+WebCache.m b/UIImageView+WebCache.m index 7164345..bd0a37a 100644 --- a/UIImageView+WebCache.m +++ b/UIImageView+WebCache.m @@ -35,6 +35,33 @@ } } +#if NS_BLOCKS_AVAILABLE +- (void)setImageWithURL:(NSURL *)url success:(void (^)(UIImage *image))success failure:(void (^)(NSError *error))failure; +{ + [self setImageWithURL:url placeholderImage:nil success:success failure:failure]; +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder success:(void (^)(UIImage *image))success failure:(void (^)(NSError *error))failure; +{ + [self setImageWithURL:url placeholderImage:placeholder options:0 success:success failure:failure]; +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options success:(void (^)(UIImage *image))success failure:(void (^)(NSError *error))failure; +{ + SDWebImageManager *manager = [SDWebImageManager sharedManager]; + + // Remove in progress downloader from queue + [manager cancelForDelegate:self]; + + self.image = placeholder; + + if (url) + { + [manager downloadWithURL:url delegate:self options:options success:success failure:failure]; + } +} +#endif + - (void)cancelCurrentImageLoad { [[SDWebImageManager sharedManager] cancelForDelegate:self];