diff --git a/Examples/SDWebImage Demo/MasterViewController.m b/Examples/SDWebImage Demo/MasterViewController.m index 67951ee8..8300c59f 100644 --- a/Examples/SDWebImage Demo/MasterViewController.m +++ b/Examples/SDWebImage Demo/MasterViewController.m @@ -372,7 +372,7 @@ cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } - cell.textLabel.text = [NSString stringWithFormat:@"Image #%d", indexPath.row]; + cell.textLabel.text = [NSString stringWithFormat:@"Image #%ld", (long)indexPath.row]; cell.imageView.contentMode = UIViewContentModeScaleAspectFill; [cell.imageView setImageWithURL:[NSURL URLWithString:[_objects objectAtIndex:indexPath.row]] placeholderImage:[UIImage imageNamed:@"placeholder"] options:indexPath.row == 0 ? SDWebImageRefreshCached : 0]; diff --git a/SDWebImage.xcodeproj/project.pbxproj b/SDWebImage.xcodeproj/project.pbxproj index a6cf909b..41447118 100644 --- a/SDWebImage.xcodeproj/project.pbxproj +++ b/SDWebImage.xcodeproj/project.pbxproj @@ -384,20 +384,20 @@ 53922DA9148C562D0056699D /* Categories */ = { isa = PBXGroup; children = ( - ABBE71A518C43B4D00B75E91 /* UIImageView+HighlightedWebCache.h */, - ABBE71A618C43B4D00B75E91 /* UIImageView+HighlightedWebCache.m */, - 5D5B9140188EE8DD006D06BD /* NSData+ImageContentType.h */, - 5D5B9141188EE8DD006D06BD /* NSData+ImageContentType.m */, - 53EDFB8817623F7C00698166 /* UIImage+MultiFormat.h */, - 53EDFB8917623F7C00698166 /* UIImage+MultiFormat.m */, - A18A6CC5172DC28500419892 /* UIImage+GIF.h */, - A18A6CC6172DC28500419892 /* UIImage+GIF.m */, - 53EDFB911762547C00698166 /* UIImage+WebP.h */, - 53EDFB921762547C00698166 /* UIImage+WebP.m */, 535699B415113E7300A4C397 /* MKAnnotationView+WebCache.h */, 535699B515113E7300A4C397 /* MKAnnotationView+WebCache.m */, + 5D5B9140188EE8DD006D06BD /* NSData+ImageContentType.h */, + 5D5B9141188EE8DD006D06BD /* NSData+ImageContentType.m */, 53922D93148C56230056699D /* UIButton+WebCache.h */, 53922D94148C56230056699D /* UIButton+WebCache.m */, + A18A6CC5172DC28500419892 /* UIImage+GIF.h */, + A18A6CC6172DC28500419892 /* UIImage+GIF.m */, + 53EDFB8817623F7C00698166 /* UIImage+MultiFormat.h */, + 53EDFB8917623F7C00698166 /* UIImage+MultiFormat.m */, + 53EDFB911762547C00698166 /* UIImage+WebP.h */, + 53EDFB921762547C00698166 /* UIImage+WebP.m */, + ABBE71A518C43B4D00B75E91 /* UIImageView+HighlightedWebCache.h */, + ABBE71A618C43B4D00B75E91 /* UIImageView+HighlightedWebCache.m */, 53922D95148C56230056699D /* UIImageView+WebCache.h */, 53922D96148C56230056699D /* UIImageView+WebCache.m */, AB615301192DA24600A2D8E9 /* UIView+WebCacheOperation.h */, diff --git a/SDWebImage/MKAnnotationView+WebCache.h b/SDWebImage/MKAnnotationView+WebCache.h index 2be81c5b..2f9a8f77 100644 --- a/SDWebImage/MKAnnotationView+WebCache.h +++ b/SDWebImage/MKAnnotationView+WebCache.h @@ -18,82 +18,86 @@ * Get the current image URL. * * Note that because of the limitations of categories this property can get out of sync - * if you use setImage: directly. + * if you use sd_setImage: directly. */ - (NSURL *)imageURL; /** * Set the imageView `image` with an `url`. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * * @param url The url for the image. */ -- (void)setImageWithURL:(NSURL *)url; +- (void)sd_setImageWithURL:(NSURL *)url; /** * Set the imageView `image` with an `url` and a placeholder. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the 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: + * @see sd_setImageWithURL:placeholderImage:options: */ -- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; /** * Set the imageView `image` with an `url`, placeholder and custom options. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the image. + * @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 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; + +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; /** * Set the imageView `image` with an `url`. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the image. - * @param completedBlock A block called when operation has been completed. This block as no return value + * @param url The url for the image. + * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. */ -- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock; /** * Set the imageView `image` with an `url`, placeholder. * - * The downloand is asynchronous and cached. + * The download 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 completedBlock A block called when operation has been completed. This block as no return value + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. */ -- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock; /** * Set the imageView `image` with an `url`, placeholder and custom options. * - * The downloand is asynchronous and cached. + * The download 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 completedBlock A block called when operation has been completed. This block as no return value + * @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 completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. */ -- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; /** * Cancel the current download @@ -101,3 +105,16 @@ - (void)cancelCurrentImageLoad; @end + + +@interface MKAnnotationView (WebCacheDeprecated) + +- (void)setImageWithURL:(NSURL *)url __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:`"); +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:`"); +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options:`"); + +- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:completed:`"); +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:completed:`"); +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options:completed:`"); + +@end diff --git a/SDWebImage/MKAnnotationView+WebCache.m b/SDWebImage/MKAnnotationView+WebCache.m index 4ceaba85..904ba0ad 100644 --- a/SDWebImage/MKAnnotationView+WebCache.m +++ b/SDWebImage/MKAnnotationView+WebCache.m @@ -14,33 +14,31 @@ static char imageURLKey; @implementation MKAnnotationView (WebCache) -- (NSURL *)imageURL; -{ +- (NSURL *)imageURL { return objc_getAssociatedObject(self, &imageURLKey); } -- (void)setImageWithURL:(NSURL *)url -{ - [self setImageWithURL:url placeholderImage:nil options:0 completed:nil]; +- (void)sd_setImageWithURL:(NSURL *)url { + [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:nil]; } -- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder { - [self setImageWithURL:url placeholderImage:placeholder options:0 completed:nil]; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:nil]; } -- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { - [self setImageWithURL:url placeholderImage:placeholder options:options completed:nil]; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:nil]; } -- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock { - [self setImageWithURL:url placeholderImage:nil options:0 completed:completedBlock]; +- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:completedBlock]; } -- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock { - [self setImageWithURL:url placeholderImage:placeholder options:0 completed:completedBlock]; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:completedBlock]; } -- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { [self cancelCurrentImageLoad]; objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); @@ -48,7 +46,7 @@ static char imageURLKey; if (url) { __weak MKAnnotationView *wself = self; - id operation = [SDWebImageManager.sharedManager downloadWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) { + id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (!wself) return; dispatch_main_sync_safe(^{ __strong MKAnnotationView *sself = wself; @@ -57,11 +55,18 @@ static char imageURLKey; sself.image = image; } if (completedBlock && finished) { - completedBlock(image, error, cacheType); + completedBlock(image, error, cacheType, url); } }); }]; [self setImageLoadOperation:operation forKey:@"MKAnnotationViewImage"]; + } else { + dispatch_main_async_safe(^{ + NSError *error = [NSError errorWithDomain:@"SDWebImageErrorDomain" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; + if (completedBlock) { + completedBlock(nil, error, SDImageCacheTypeNone, url); + } + }); } } @@ -70,3 +75,44 @@ static char imageURLKey; } @end + + +@implementation MKAnnotationView (WebCacheDeprecated) + +- (void)setImageWithURL:(NSURL *)url { + [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:nil]; +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:nil]; +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:nil]; +} + +- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +@end diff --git a/SDWebImage/NSData+ImageContentType.h b/SDWebImage/NSData+ImageContentType.h index bb78bb0c..9ad2dfe8 100644 --- a/SDWebImage/NSData+ImageContentType.h +++ b/SDWebImage/NSData+ImageContentType.h @@ -6,5 +6,14 @@ #import @interface NSData (ImageContentType) + +/** + * Compute the content type for an image data + * + * @param data the input data + * + * @return the content type as string (i.e. image/jpeg, image/gif) + */ + (NSString *)contentTypeForImageData:(NSData *)data; + @end diff --git a/SDWebImage/SDImageCache.h b/SDWebImage/SDImageCache.h index df4eebdc..97cc7485 100644 --- a/SDWebImage/SDImageCache.h +++ b/SDWebImage/SDImageCache.h @@ -73,15 +73,15 @@ typedef void(^SDWebImageQueryCompletedBlock)(UIImage *image, SDImageCacheType ca * Store an image into memory and disk cache at the given key. * * @param image The image to store - * @param key The unique image cache key, usually it's image absolute URL + * @param key The unique image cache key, usually it's image absolute URL */ - (void)storeImage:(UIImage *)image forKey:(NSString *)key; /** * Store an image into memory and optionally disk cache at the given key. * - * @param image The image to store - * @param key The unique image cache key, usually it's image absolute URL + * @param image The image to store + * @param key The unique image cache key, usually it's image absolute URL * @param toDisk Store the image to disk cache if YES */ - (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk; @@ -89,13 +89,13 @@ typedef void(^SDWebImageQueryCompletedBlock)(UIImage *image, SDImageCacheType ca /** * Store an image into memory and optionally disk cache at the given key. * - * @param image The image to store + * @param image The image to store * @param recalculate BOOL indicates if imageData can be used or a new data should be constructed from the UIImage - * @param imageData The image data as returned by the server, this representation will be used for disk storage - * instead of converting the given image object into a storable/compressed image format in order - * to save quality and CPU - * @param key The unique image cache key, usually it's image absolute URL - * @param toDisk Store the image to disk cache if YES + * @param imageData The image data as returned by the server, this representation will be used for disk storage + * instead of converting the given image object into a storable/compressed image format in order + * to save quality and CPU + * @param key The unique image cache key, usually it's image absolute URL + * @param toDisk Store the image to disk cache if YES */ - (void)storeImage:(UIImage *)image recalculateFromImage:(BOOL)recalculate imageData:(NSData *)imageData forKey:(NSString *)key toDisk:(BOOL)toDisk; @@ -131,7 +131,7 @@ typedef void(^SDWebImageQueryCompletedBlock)(UIImage *image, SDImageCacheType ca /** * Remove the image from memory and disk cache synchronously * - * @param key The unique image cache key + * @param key The unique image cache key * @param completionBlock An block that should be executed after the image has been removed (optional) */ - (void)removeImageForKey:(NSString *)key withCompletition:(void (^)())completion; @@ -139,7 +139,7 @@ typedef void(^SDWebImageQueryCompletedBlock)(UIImage *image, SDImageCacheType ca /** * Remove the image from memory and optionally disk cache synchronously * - * @param key The unique image cache key + * @param key The unique image cache key * @param fromDisk Also remove cache entry from disk if YES */ - (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk; @@ -147,8 +147,8 @@ typedef void(^SDWebImageQueryCompletedBlock)(UIImage *image, SDImageCacheType ca /** * Remove the image from memory and optionally disk cache synchronously * - * @param key The unique image cache key - * @param fromDisk Also remove cache entry from disk if YES + * @param key The unique image cache key + * @param fromDisk Also remove cache entry from disk if YES * @param completionBlock An block that should be executed after the image has been removed (optional) */ - (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk withCompletition:(void (^)())completion; diff --git a/SDWebImage/SDWebImageCompat.h b/SDWebImage/SDWebImageCompat.h index 2d90d3ca..3d8d6360 100644 --- a/SDWebImage/SDWebImageCompat.h +++ b/SDWebImage/SDWebImageCompat.h @@ -56,7 +56,13 @@ extern UIImage *SDScaledImageForKey(NSString *key, UIImage *image); #define dispatch_main_sync_safe(block)\ if ([NSThread isMainThread]) {\ block();\ - }\ - else {\ + } else {\ dispatch_sync(dispatch_get_main_queue(), block);\ } + +#define dispatch_main_async_safe(block)\ + if ([NSThread isMainThread]) {\ + block();\ + } else {\ + dispatch_async(dispatch_get_main_queue(), block);\ + } diff --git a/SDWebImage/SDWebImageCompat.m b/SDWebImage/SDWebImageCompat.m index 7f911535..8c7d345a 100644 --- a/SDWebImage/SDWebImageCompat.m +++ b/SDWebImage/SDWebImageCompat.m @@ -13,6 +13,10 @@ #endif inline UIImage *SDScaledImageForKey(NSString *key, UIImage *image) { + if (!image) { + return nil; + } + if ([image.images count] > 0) { NSMutableArray *scaledImages = [NSMutableArray array]; diff --git a/SDWebImage/SDWebImageDownloader.h b/SDWebImage/SDWebImageDownloader.h index ffe5aa9d..edbe7104 100644 --- a/SDWebImage/SDWebImageDownloader.h +++ b/SDWebImage/SDWebImageDownloader.h @@ -129,17 +129,17 @@ typedef void(^SDWebImageDownloaderCompletedBlock)(UIImage *image, NSData *data, * * @see SDWebImageDownloaderDelegate * - * @param url The URL to the image to download - * @param options The options to be used for this download - * @param progressBlock A block called repeatedly while the image is downloading + * @param url The URL to the image to download + * @param options The options to be used for this download + * @param progressBlock A block called repeatedly while the image is downloading * @param completedBlock A block called once the download is completed. - * If the download succeeded, the image parameter is set, in case of error, - * error parameter is set with the error. The last parameter is always YES - * if SDWebImageDownloaderProgressiveDownload isn't use. With the - * SDWebImageDownloaderProgressiveDownload option, this block is called - * repeatedly with the partial image object and the finished argument set to NO - * before to be called a last time with the full image and finished argument - * set to YES. In case of error, the finished argument is always YES. + * If the download succeeded, the image parameter is set, in case of error, + * error parameter is set with the error. The last parameter is always YES + * if SDWebImageDownloaderProgressiveDownload isn't use. With the + * SDWebImageDownloaderProgressiveDownload option, this block is called + * repeatedly with the partial image object and the finished argument set to NO + * before to be called a last time with the full image and finished argument + * set to YES. In case of error, the finished argument is always YES. * * @return A cancellable SDWebImageOperation */ diff --git a/SDWebImage/SDWebImageDownloader.m b/SDWebImage/SDWebImageDownloader.m index 09ceb4f9..a67eb9dc 100644 --- a/SDWebImage/SDWebImageDownloader.m +++ b/SDWebImage/SDWebImageDownloader.m @@ -127,8 +127,8 @@ static NSString *const kCompletedCallbackKey = @"completed"; operation = [[SDWebImageDownloaderOperation alloc] initWithRequest:request options:options progress:^(NSInteger receivedSize, NSInteger expectedSize) { - if (!wself) return; SDWebImageDownloader *sself = wself; + if (!sself) return; NSArray *callbacksForURL = [sself callbacksForURL:url]; for (NSDictionary *callbacks in callbacksForURL) { SDWebImageDownloaderProgressBlock callback = callbacks[kProgressCallbackKey]; @@ -136,8 +136,8 @@ static NSString *const kCompletedCallbackKey = @"completed"; } } completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) { - if (!wself) return; SDWebImageDownloader *sself = wself; + if (!sself) return; NSArray *callbacksForURL = [sself callbacksForURL:url]; if (finished) { [sself removeCallbacksForURL:url]; @@ -148,13 +148,15 @@ static NSString *const kCompletedCallbackKey = @"completed"; } } cancelled:^{ - if (!wself) return; SDWebImageDownloader *sself = wself; + if (!sself) return; [sself removeCallbacksForURL:url]; }]; if (options & SDWebImageDownloaderHighPriority) { operation.queuePriority = NSOperationQueuePriorityHigh; + } else if (options & SDWebImageDownloaderLowPriority) { + operation.queuePriority = NSOperationQueuePriorityLow; } [wself.downloadQueue addOperation:operation]; diff --git a/SDWebImage/SDWebImageDownloaderOperation.m b/SDWebImage/SDWebImageDownloaderOperation.m index a0b7db2f..b93be75a 100644 --- a/SDWebImage/SDWebImageDownloaderOperation.m +++ b/SDWebImage/SDWebImageDownloaderOperation.m @@ -10,6 +10,7 @@ #import "SDWebImageDecoder.h" #import "UIImage+MultiFormat.h" #import +#import "SDWebImageManager.h" @interface SDWebImageDownloaderOperation () { BOOL _executing; @@ -285,7 +286,8 @@ if (partialImageRef) { UIImage *image = [UIImage imageWithCGImage:partialImageRef scale:1 orientation:orientation]; - UIImage *scaledImage = [self scaledImageForKey:self.request.URL.absoluteString image:image]; + NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:self.request.URL]; + UIImage *scaledImage = [self scaledImageForKey:key image:image]; image = [UIImage decodedImageWithImage:scaledImage]; CGImageRelease(partialImageRef); dispatch_main_sync_safe(^{ @@ -353,7 +355,8 @@ UIImage *image = [UIImage sd_imageWithData:self.imageData]; - image = [self scaledImageForKey:self.request.URL.absoluteString image:image]; + NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:self.request.URL]; + image = [self scaledImageForKey:key image:image]; if (!image.images) // Do not force decod animated GIFs { diff --git a/SDWebImage/SDWebImageManager.h b/SDWebImage/SDWebImageManager.h index 6a1a17da..664b3089 100644 --- a/SDWebImage/SDWebImageManager.h +++ b/SDWebImage/SDWebImageManager.h @@ -77,9 +77,9 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) { SDWebImageDelayPlaceholder = 1 << 9 }; -typedef void(^SDWebImageCompletedBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType); +typedef void(^SDWebImageCompletionBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL); -typedef void(^SDWebImageCompletedWithFinishedBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished); +typedef void(^SDWebImageCompletionWithFinishedBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL); @class SDWebImageManager; @@ -92,7 +92,7 @@ typedef void(^SDWebImageCompletedWithFinishedBlock)(UIImage *image, NSError *err * 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 + * @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. */ @@ -103,8 +103,8 @@ typedef void(^SDWebImageCompletedWithFinishedBlock)(UIImage *image, NSError *err * 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 + * @param image The image to transform + * @param imageURL The url of the image to transform * * @return The transformed image object. */ @@ -126,7 +126,7 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; [manager downloadWithURL:imageURL options:0 progress:nil - completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) { + completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (image) { // do something with image } @@ -169,9 +169,9 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; /** * Downloads the image at the given URL if not present in cache or return the cached version otherwise. * - * @param url The URL to the image - * @param options A mask to specify options to use for this request - * @param progressBlock A block called while image is downloading + * @param url The URL to the image + * @param options A mask to specify options to use for this request + * @param progressBlock A block called while image is downloading * @param completedBlock A block called when operation has been completed. * * This parameter is required. @@ -188,16 +188,16 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; * * @return Returns an NSObject conforming to SDWebImageOperation. Should be an instance of SDWebImageDownloaderOperation */ -- (id )downloadWithURL:(NSURL *)url - options:(SDWebImageOptions)options - progress:(SDWebImageDownloaderProgressBlock)progressBlock - completed:(SDWebImageCompletedWithFinishedBlock)completedBlock; +- (id )downloadImageWithURL:(NSURL *)url + options:(SDWebImageOptions)options + progress:(SDWebImageDownloaderProgressBlock)progressBlock + completed:(SDWebImageCompletionWithFinishedBlock)completedBlock; /** * Saves image to cache for given URL * * @param image The image to cache - * @param url The URL to the image + * @param url The URL to the image * */ @@ -225,3 +225,24 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; - (NSString *)cacheKeyForURL:(NSURL *)url; @end + + +#pragma mark - Deprecated + +typedef void(^SDWebImageCompletedBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType) __deprecated_msg("Block type deprecated. Use `SDWebImageCompletionBlock`"); +typedef void(^SDWebImageCompletedWithFinishedBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) __deprecated_msg("Block type deprecated. Use `SDWebImageCompletionWithFinishedBlock`"); + + +@interface SDWebImageManager (Deprecated) + +/** + * Downloads the image at the given URL if not present in cache or return the cached version otherwise. + * + * @deprecated This method has been deprecated. Use `downloadImageWithURL:options:progress:completed:` + */ +- (id )downloadWithURL:(NSURL *)url + options:(SDWebImageOptions)options + progress:(SDWebImageDownloaderProgressBlock)progressBlock + completed:(SDWebImageCompletedWithFinishedBlock)completedBlock __deprecated_msg("Method deprecated. Use `downloadImageWithURL:options:progress:completed:`"); + +@end diff --git a/SDWebImage/SDWebImageManager.m b/SDWebImage/SDWebImageManager.m index 7c256612..f030a627 100644 --- a/SDWebImage/SDWebImageManager.m +++ b/SDWebImage/SDWebImageManager.m @@ -71,7 +71,10 @@ return [self.imageCache diskImageExistsWithKey:key]; } -- (id )downloadWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedWithFinishedBlock)completedBlock { +- (id )downloadImageWithURL:(NSURL *)url + options:(SDWebImageOptions)options + progress:(SDWebImageDownloaderProgressBlock)progressBlock + completed:(SDWebImageCompletionWithFinishedBlock)completedBlock { // Invoking this method without a completedBlock is pointless NSParameterAssert(completedBlock); @@ -97,7 +100,7 @@ if (!url || (!(options & SDWebImageRetryFailed) && isFailedUrl)) { dispatch_main_sync_safe(^{ NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil]; - completedBlock(nil, error, SDImageCacheTypeNone, YES); + completedBlock(nil, error, SDImageCacheTypeNone, YES, url); }); return operation; } @@ -121,7 +124,7 @@ dispatch_main_sync_safe(^{ // If image was found in the cache bug SDWebImageRefreshCached is provided, notify about the cached image // AND try to re-download it in order to let a chance to NSURLCache to refresh it from server. - completedBlock(image, nil, cacheType, YES); + completedBlock(image, nil, cacheType, YES, url); }); } @@ -143,12 +146,12 @@ id subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(UIImage *downloadedImage, NSData *data, NSError *error, BOOL finished) { if (weakOperation.isCancelled) { dispatch_main_sync_safe(^{ - completedBlock(nil, nil, SDImageCacheTypeNone, finished); + completedBlock(nil, nil, SDImageCacheTypeNone, finished, url); }); } else if (error) { dispatch_main_sync_safe(^{ - completedBlock(nil, error, SDImageCacheTypeNone, finished); + completedBlock(nil, error, SDImageCacheTypeNone, finished, url); }); if (error.code != NSURLErrorNotConnectedToInternet && error.code != NSURLErrorCancelled && error.code != NSURLErrorTimedOut) { @@ -174,7 +177,7 @@ } dispatch_main_sync_safe(^{ - completedBlock(transformedImage, nil, SDImageCacheTypeNone, finished); + completedBlock(transformedImage, nil, SDImageCacheTypeNone, finished, url); }); }); } @@ -184,7 +187,7 @@ } dispatch_main_sync_safe(^{ - completedBlock(downloadedImage, nil, SDImageCacheTypeNone, finished); + completedBlock(downloadedImage, nil, SDImageCacheTypeNone, finished, url); }); } } @@ -205,7 +208,7 @@ } else if (image) { dispatch_main_sync_safe(^{ - completedBlock(image, nil, cacheType, YES); + completedBlock(image, nil, cacheType, YES, url); }); @synchronized (self.runningOperations) { [self.runningOperations removeObject:operation]; @@ -214,7 +217,7 @@ else { // Image not in cache and download disallowed by delegate dispatch_main_sync_safe(^{ - completedBlock(nil, nil, SDImageCacheTypeNone, YES); + completedBlock(nil, nil, SDImageCacheTypeNone, YES, url); }); @synchronized (self.runningOperations) { [self.runningOperations removeObject:operation]; @@ -245,6 +248,7 @@ @end + @implementation SDWebImageCombinedOperation - (void)setCancelBlock:(void (^)())cancelBlock { @@ -269,3 +273,21 @@ } @end + + +@implementation SDWebImageManager (Deprecated) + +// deprecated method, uses the non deprecated method +// adapter for the completion block +- (id )downloadWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedWithFinishedBlock)completedBlock { + return [self downloadImageWithURL:url + options:options + progress:progressBlock + completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType, finished); + } + }]; +} + +@end diff --git a/SDWebImage/SDWebImagePrefetcher.h b/SDWebImage/SDWebImagePrefetcher.h index af33db4e..3829033a 100644 --- a/SDWebImage/SDWebImagePrefetcher.h +++ b/SDWebImage/SDWebImagePrefetcher.h @@ -19,17 +19,17 @@ * Called when an image was prefetched. * * @param imagePrefetcher The current image prefetcher - * @param imageURL The image url that was prefetched - * @param finishedCount The total number of images that were prefetched - * @param totalCount The total number of images that need to be prefetched + * @param imageURL The image url that was prefetched + * @param finishedCount The total number of images that were prefetched (successful or not) + * @param totalCount The total number of images that were to be prefetched */ - (void)imagePrefetcher:(SDWebImagePrefetcher *)imagePrefetcher didPrefetchURL:(NSURL *)imageURL finishedCount:(NSUInteger)finishedCount totalCount:(NSUInteger)totalCount; /** * Called when all images are prefetched. * @param imagePrefetcher The current image prefetcher - * @param totalCount The total number of images that need to be prefetched - * @param skippedCount The total number of images that were skipped + * @param totalCount The total number of images that were prefetched (whether successful or not) + * @param skippedCount The total number of images that were skipped */ - (void)imagePrefetcher:(SDWebImagePrefetcher *)imagePrefetcher didFinishWithTotalCount:(NSUInteger)totalCount skippedCount:(NSUInteger)skippedCount; @@ -77,8 +77,10 @@ * currently one image is downloaded at a time, * and skips images for failed downloads and proceed to the next image in the list * - * @param urls list of URLs to prefetch - * @param progressBlock block to be called when progress updates + * @param urls list of URLs to prefetch + * @param progressBlock block to be called when progress updates; + * first parameter is the number of completed (successful or not) requests, + * second parameter is the total number of images originally requested to be prefetched * @param completionBlock block to be called when prefetching is completed */ - (void)prefetchURLs:(NSArray *)urls progress:(void (^)(NSUInteger, NSUInteger))progressBlock completed:(void (^)(NSUInteger, NSUInteger))completionBlock; diff --git a/SDWebImage/SDWebImagePrefetcher.m b/SDWebImage/SDWebImagePrefetcher.m index 74a3bc1e..8f959f6f 100644 --- a/SDWebImage/SDWebImagePrefetcher.m +++ b/SDWebImage/SDWebImagePrefetcher.m @@ -56,7 +56,7 @@ - (void)startPrefetchingAtIndex:(NSUInteger)index { if (index >= self.prefetchURLs.count) return; self.requestedCount++; - [self.manager downloadWithURL:self.prefetchURLs[index] options:self.options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) { + [self.manager downloadImageWithURL:self.prefetchURLs[index] options:self.options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (!finished) return; self.finishedCount++; @@ -88,7 +88,7 @@ [self startPrefetchingAtIndex:self.requestedCount]; }); } - else if (self.finishedCount + self.skippedCount == self.requestedCount) { + else if (self.finishedCount == self.requestedCount) { [self reportStatus]; if (self.completionBlock) { self.completionBlock(self.finishedCount, self.skippedCount); diff --git a/SDWebImage/UIButton+WebCache.h b/SDWebImage/UIButton+WebCache.h index cd6316cd..6a6fdc7b 100644 --- a/SDWebImage/UIButton+WebCache.h +++ b/SDWebImage/UIButton+WebCache.h @@ -29,159 +29,165 @@ /** * Set the imageView `image` with an `url`. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the image. + * @param url The url for the image. * @param state The state that uses the specified title. The values are described in UIControlState. */ -- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state; +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state; /** * Set the imageView `image` with an `url` and a placeholder. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the image. - * @param state The state that uses the specified title. The values are described in UIControlState. + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. * @param placeholder The image to be set initially, until the image request finishes. - * @see setImageWithURL:placeholderImage:options: + * @see sd_setImageWithURL:placeholderImage:options: */ -- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder; +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder; /** * Set the imageView `image` with an `url`, placeholder and custom options. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the image. - * @param state The state that uses the specified title. The values are described in UIControlState. + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. * @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 options The options to use when downloading the image. @see SDWebImageOptions for the possible values. */ -- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; /** * Set the imageView `image` with an `url`. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the image. - * @param state The state that uses the specified title. The values are described in UIControlState. - * @param completedBlock A block called when operation has been completed. This block as no return value + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. */ -- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletedBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock; /** * Set the imageView `image` with an `url`, placeholder. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the image. - * @param state The state that uses the specified title. The values are described in UIControlState. - * @param placeholder The image to be set initially, until the image request finishes. - * @param completedBlock A block called when operation has been completed. This block as no return value + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. */ -- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock; /** * Set the imageView `image` with an `url`, placeholder and custom options. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the image. - * @param state The state that uses the specified title. The values are described in UIControlState. - * @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 completedBlock A block called when operation has been completed. This block as no return value + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @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 completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. */ -- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; /** * Set the backgroundImageView `image` with an `url`. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the image. + * @param url The url for the image. * @param state The state that uses the specified title. The values are described in UIControlState. */ -- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state; +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state; /** * Set the backgroundImageView `image` with an `url` and a placeholder. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the image. - * @param state The state that uses the specified title. The values are described in UIControlState. + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. * @param placeholder The image to be set initially, until the image request finishes. - * @see setImageWithURL:placeholderImage:options: + * @see sd_setImageWithURL:placeholderImage:options: */ -- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder; +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder; /** * Set the backgroundImageView `image` with an `url`, placeholder and custom options. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the image. - * @param state The state that uses the specified title. The values are described in UIControlState. + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. * @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 options The options to use when downloading the image. @see SDWebImageOptions for the possible values. */ -- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; /** * Set the backgroundImageView `image` with an `url`. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the image. - * @param state The state that uses the specified title. The values are described in UIControlState. - * @param completedBlock A block object to be executed after the request operation - * completed. This block has no return value and takes three argument: the requested - * `UIImage` object, the `NSError` object describing error that occurred, and an - * `SDImageCacheType` enum describing the source of the image obtained from. + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. */ -- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletedBlock)completedBlock; +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock; /** * Set the backgroundImageView `image` with an `url`, placeholder. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the image. - * @param state The state that uses the specified title. The values are described in UIControlState. - * @param placeholder The image to be set initially, until the image request finishes. - * @param completedBlock A block object to be executed after the request operation - * completed. This block has no return value and takes three argument: the requested - * `UIImage` object, the `NSError` object describing error that occurred, and an - * `SDImageCacheType` enum describing the source of the image obtained from. + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. */ -- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock; +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock; /** * Set the backgroundImageView `image` with an `url`, placeholder and custom options. * - * The downloand is asynchronous and cached. + * The download 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 completedBlock A block object to be executed after the request operation - * completed. This block has no return value and takes three argument: the requested - * `UIImage` object, the `NSError` object describing error that occurred, and an - * `SDImageCacheType` enum describing the source of the image obtained from. + * @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 completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. */ -- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock; +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; /** * Cancel the current image download @@ -194,3 +200,24 @@ - (void)cancelBackgroundImageLoadForState:(UIControlState)state; @end + + +@interface UIButton (WebCacheDeprecated) + +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:`"); +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:placeholderImage:`"); +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:placeholderImage:options:`"); + +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:completed:`"); +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:placeholderImage:completed:`"); +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:placeholderImage:options:completed:`"); + +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:`"); +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:placeholderImage:`"); +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:placeholderImage:options:`"); + +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:completed:`"); +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:placeholderImage:completed:`"); +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:placeholderImage:options:completed:`"); + +@end diff --git a/SDWebImage/UIButton+WebCache.m b/SDWebImage/UIButton+WebCache.m index f574af6a..f86b4520 100644 --- a/SDWebImage/UIButton+WebCache.m +++ b/SDWebImage/UIButton+WebCache.m @@ -14,45 +14,41 @@ static char imageURLStorageKey; @implementation UIButton (WebCache) -- (NSURL *)currentImageURL; -{ +- (NSURL *)currentImageURL { NSURL *url = self.imageURLStorage[@(self.state)]; - if (!url) - { + if (!url) { url = self.imageURLStorage[@(UIControlStateNormal)]; } return url; } -- (NSURL *)imageURLForState:(UIControlState)state; -{ +- (NSURL *)imageURLForState:(UIControlState)state { return self.imageURLStorage[@(state)]; } -- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state -{ - [self setImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state { + [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; } -- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder { - [self setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil]; +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil]; } -- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { - [self setImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil]; +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil]; } -- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletedBlock)completedBlock { - [self setImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock]; +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock]; } -- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock { - [self setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock]; +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock]; } -- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { [self setImage:placeholder forState:state]; [self cancelImageLoadForState:state]; @@ -60,13 +56,20 @@ static char imageURLStorageKey; if (!url) { [self.imageURLStorage removeObjectForKey:@(state)]; + dispatch_main_async_safe(^{ + NSError *error = [NSError errorWithDomain:@"SDWebImageErrorDomain" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; + if (completedBlock) { + completedBlock(nil, error, SDImageCacheTypeNone, url); + } + }); + return; } self.imageURLStorage[@(state)] = url; __weak UIButton *wself = self; - id operation = [SDWebImageManager.sharedManager downloadWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) { + id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (!wself) return; dispatch_main_sync_safe(^{ __strong UIButton *sself = wself; @@ -75,41 +78,41 @@ static char imageURLStorageKey; [sself setImage:image forState:state]; } if (completedBlock && finished) { - completedBlock(image, error, cacheType); + completedBlock(image, error, cacheType, url); } }); }]; [self setImageLoadOperation:operation forState:state]; } -- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state { - [self setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; } -- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder { - [self setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil]; +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil]; } -- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { - [self setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil]; +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil]; } -- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletedBlock)completedBlock { - [self setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock]; +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock]; } -- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock { - [self setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock]; +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock]; } -- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { [self cancelImageLoadForState:state]; [self setBackgroundImage:placeholder forState:state]; if (url) { __weak UIButton *wself = self; - id operation = [SDWebImageManager.sharedManager downloadWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) { + id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (!wself) return; dispatch_main_sync_safe(^{ __strong UIButton *sself = wself; @@ -118,11 +121,18 @@ static char imageURLStorageKey; [sself setBackgroundImage:image forState:state]; } if (completedBlock && finished) { - completedBlock(image, error, cacheType); + completedBlock(image, error, cacheType, url); } }); }]; [self setBackgroundImageLoadOperation:operation forState:state]; + } else { + dispatch_main_async_safe(^{ + NSError *error = [NSError errorWithDomain:@"SDWebImageErrorDomain" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; + if (completedBlock) { + completedBlock(nil, error, SDImageCacheTypeNone, url); + } + }); } } @@ -142,8 +152,7 @@ static char imageURLStorageKey; [self cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]]; } -- (NSMutableDictionary *)imageURLStorage; -{ +- (NSMutableDictionary *)imageURLStorage { NSMutableDictionary *storage = objc_getAssociatedObject(self, &imageURLStorageKey); if (!storage) { @@ -155,3 +164,80 @@ static char imageURLStorageKey; } @end + + +@implementation UIButton (WebCacheDeprecated) + +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state { + [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; +} + +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil]; +} + +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil]; +} + +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; +} + +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil]; +} + +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil]; +} + +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +@end diff --git a/SDWebImage/UIImage+MultiFormat.m b/SDWebImage/UIImage+MultiFormat.m index e2e3e80f..90f55628 100644 --- a/SDWebImage/UIImage+MultiFormat.m +++ b/SDWebImage/UIImage+MultiFormat.m @@ -9,6 +9,7 @@ #import "UIImage+MultiFormat.h" #import "UIImage+GIF.h" #import "NSData+ImageContentType.h" +#import #ifdef SD_WEBP #import "UIImage+WebP.h" @@ -30,10 +31,82 @@ #endif else { image = [[UIImage alloc] initWithData:data]; + UIImageOrientation orientation = [self sd_imageOrientationFromImageData:data]; + if (orientation != UIImageOrientationUp) { + image = [UIImage imageWithCGImage:image.CGImage + scale:image.scale + orientation:orientation]; + } } return image; } + ++(UIImageOrientation)sd_imageOrientationFromImageData:(NSData *)imageData { + UIImageOrientation result = UIImageOrientationUp; + CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL); + CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL); + if (properties) { + CFTypeRef val; + int exifOrientation; + val = CFDictionaryGetValue(properties, kCGImagePropertyOrientation); + if (val) { + CFNumberGetValue(val, kCFNumberIntType, &exifOrientation); + result = [self sd_exifOrientationToiOSOrientation:exifOrientation]; + } // else - if it's not set it remains at up + CFRelease((CFTypeRef) properties); + } else { + //NSLog(@"NO PROPERTIES, FAIL"); + } + CFRelease(imageSource); + return result; +} + +#pragma EXIF orientation tag converter +// Convert an EXIF image orientation to an iOS one. +// reference see here: http://sylvana.net/jpegcrop/exif_orientation.html ++ (UIImageOrientation) sd_exifOrientationToiOSOrientation:(int)exifOrientation { + UIImageOrientation orientation = UIImageOrientationUp; + switch (exifOrientation) { + case 1: + orientation = UIImageOrientationUp; + break; + + case 3: + orientation = UIImageOrientationDown; + break; + + case 8: + orientation = UIImageOrientationLeft; + break; + + case 6: + orientation = UIImageOrientationRight; + break; + + case 2: + orientation = UIImageOrientationUpMirrored; + break; + + case 4: + orientation = UIImageOrientationDownMirrored; + break; + + case 5: + orientation = UIImageOrientationLeftMirrored; + break; + + case 7: + orientation = UIImageOrientationRightMirrored; + break; + default: + break; + } + return orientation; +} + + + @end diff --git a/SDWebImage/UIImageView+HighlightedWebCache.h b/SDWebImage/UIImageView+HighlightedWebCache.h index 9e15a1dd..ee18d751 100644 --- a/SDWebImage/UIImageView+HighlightedWebCache.h +++ b/SDWebImage/UIImageView+HighlightedWebCache.h @@ -18,62 +18,66 @@ /** * Set the imageView `highlightedImage` with an `url`. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * * @param url The url for the image. */ -- (void)setHighlightedImageWithURL:(NSURL *)url; +- (void)sd_setHighlightedImageWithURL:(NSURL *)url; + /** * Set the imageView `highlightedImage` with an `url` and custom options. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the image. + * @param url The url for the image. * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. */ -- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options; +- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options; /** * Set the imageView `highlightedImage` with an `url`. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the image. - * @param completedBlock A block called when operation has been completed. This block as no return value + * @param url The url for the image. + * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. */ -- (void)setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock; +- (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock; /** * Set the imageView `highlightedImage` with an `url` and custom options. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the image. - * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. - * @param completedBlock A block called when operation has been completed. This block as no return value + * @param url The url for the image. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. */ -- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock; +- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; /** * Set the imageView `highlightedImage` with an `url` and custom options. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the image. - * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. - * @param progressBlock A block called while image is downloading - * @param completedBlock A block called when operation has been completed. This block as no return value + * @param url The url for the image. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param progressBlock A block called while image is downloading + * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. */ -- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock; +- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock; /** * Cancel the current download @@ -81,3 +85,14 @@ - (void)cancelCurrentHighlightedImageLoad; @end + + +@interface UIImageView (HighlightedWebCacheDeprecated) + +- (void)setHighlightedImageWithURL:(NSURL *)url __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:`"); +- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:`"); +- (void)setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:completed:`"); +- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:completed:`"); +- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:progress:completed:`"); + +@end diff --git a/SDWebImage/UIImageView+HighlightedWebCache.m b/SDWebImage/UIImageView+HighlightedWebCache.m index 9014be94..c8f30245 100644 --- a/SDWebImage/UIImageView+HighlightedWebCache.m +++ b/SDWebImage/UIImageView+HighlightedWebCache.m @@ -13,46 +13,49 @@ @implementation UIImageView (HighlightedWebCache) -- (void)setHighlightedImageWithURL:(NSURL *)url { - [self setHighlightedImageWithURL:url options:0 progress:nil completed:nil]; +- (void)sd_setHighlightedImageWithURL:(NSURL *)url { + [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:nil]; } -- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options { - [self setHighlightedImageWithURL:url options:options progress:nil completed:nil]; +- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options { + [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil]; } -- (void)setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock { - [self setHighlightedImageWithURL:url options:0 progress:nil completed:completedBlock]; +- (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:completedBlock]; } -- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { - [self setHighlightedImageWithURL:url options:options progress:nil completed:completedBlock]; +- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:completedBlock]; } -- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock { +- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock { [self cancelCurrentHighlightedImageLoad]; if (url) { __weak UIImageView *wself = self; - id operation = [SDWebImageManager.sharedManager downloadWithURL:url - options:options - progress:progressBlock - completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) - { - if (!wself) return; - dispatch_main_sync_safe (^ - { - if (!wself) return; - if (image) { - wself.highlightedImage = image; - [wself setNeedsLayout]; - } - if (completedBlock && finished) { - completedBlock(image, error, cacheType); - } - }); - }]; + id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + if (!wself) return; + dispatch_main_sync_safe (^ + { + if (!wself) return; + if (image) { + wself.highlightedImage = image; + [wself setNeedsLayout]; + } + if (completedBlock && finished) { + completedBlock(image, error, cacheType, url); + } + }); + }]; [self setImageLoadOperation:operation forKey:UIImageViewHighlightedWebCacheOperationKey]; + } else { + dispatch_main_async_safe(^{ + NSError *error = [NSError errorWithDomain:@"SDWebImageErrorDomain" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; + if (completedBlock) { + completedBlock(nil, error, SDImageCacheTypeNone, url); + } + }); } } @@ -61,3 +64,40 @@ } @end + + +@implementation UIImageView (HighlightedWebCacheDeprecated) + +- (void)setHighlightedImageWithURL:(NSURL *)url { + [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:nil]; +} + +- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options { + [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil]; +} + +- (void)setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setHighlightedImageWithURL:url options:0 progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +@end diff --git a/SDWebImage/UIImageView+WebCache.h b/SDWebImage/UIImageView+WebCache.h index c679df69..fb56d0bb 100644 --- a/SDWebImage/UIImageView+WebCache.h +++ b/SDWebImage/UIImageView+WebCache.h @@ -31,10 +31,10 @@ autorelease]; } - // Here we use the provided setImageWithURL: method to load the web image + // Here we use the provided sd_setImageWithURL: method to load the web image // Ensure you use a placeholder image otherwise cells will be initialized with no image - [cell.imageView setImageWithURL:[NSURL URLWithString:@"http://example.com/image.jpg"] - placeholderImage:[UIImage imageNamed:@"placeholder"]]; + [cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://example.com/image.jpg"] + placeholderImage:[UIImage imageNamed:@"placeholder"]]; cell.textLabel.text = @"My Text"; return cell; @@ -48,98 +48,102 @@ * Get the current image URL. * * Note that because of the limitations of categories this property can get out of sync - * if you use setImage: directly. + * if you use sd_setImage: directly. */ - (NSURL *)imageURL; /** * Set the imageView `image` with an `url`. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * * @param url The url for the image. */ -- (void)setImageWithURL:(NSURL *)url; +- (void)sd_setImageWithURL:(NSURL *)url; /** * Set the imageView `image` with an `url` and a placeholder. * - * The downloand is asynchronous and cached. + * The download is asynchronous and cached. * - * @param url The url for the 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: + * @see sd_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; - -/** - * Set the imageView `image` with an `url`. - * - * The downloand is asynchronous and cached. - * - * @param url The url for the image. - * @param completedBlock A block called when operation has been completed. This block as no return value - * and takes the requested UIImage as first parameter. In case of error the image parameter - * is nil and the second parameter may contain an NSError. The third parameter is a Boolean - * indicating if the image was retrived from the local cache of from the network. - */ -- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock; - -/** - * 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 completedBlock A block called when operation has been completed. This block as no return value - * and takes the requested UIImage as first parameter. In case of error the image parameter - * is nil and the second parameter may contain an NSError. The third parameter is a Boolean - * indicating if the image was retrived from the local cache of from the network. - */ -- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock; - -/** - * 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 completedBlock A block called when operation has been completed. This block as no return value - * and takes the requested UIImage as first parameter. In case of error the image parameter - * is nil and the second parameter may contain an NSError. The third parameter is a Boolean - * indicating if the image was retrived from the local cache of from the network. - */ -- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; /** * Set the imageView `image` with an `url`, placeholder and custom options. * * The download is asynchronous and cached. * - * @param url The url for the image. + * @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 progressBlock A block called while image is downloading - * @param completedBlock A block called when operation has been completed. This block as no return value + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + */ +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; + +/** + * Set the imageView `image` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. */ -- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock; + +/** + * Set the imageView `image` with an `url`, placeholder. + * + * The download 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 completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock; + +/** + * Set the imageView `image` with an `url`, placeholder and custom options. + * + * The download 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 completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; + +/** + * Set the imageView `image` with an `url`, placeholder and custom options. + * + * The download 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 progressBlock A block called while image is downloading + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock; /** * Download an array of images and starts them in an animation loop @@ -156,3 +160,17 @@ - (void)cancelCurrentAnimationImagesLoad; @end + + +@interface UIImageView (WebCacheDeprecated) + +- (void)setImageWithURL:(NSURL *)url __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:`"); +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:`"); +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options`"); + +- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:completed:`"); +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:completed:`"); +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options:completed:`"); +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options:progress:completed:`"); + +@end diff --git a/SDWebImage/UIImageView+WebCache.m b/SDWebImage/UIImageView+WebCache.m index f9d508a6..1caf4caf 100644 --- a/SDWebImage/UIImageView+WebCache.m +++ b/SDWebImage/UIImageView+WebCache.m @@ -14,31 +14,31 @@ static char imageURLKey; @implementation UIImageView (WebCache) -- (void)setImageWithURL:(NSURL *)url { - [self setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil]; +- (void)sd_setImageWithURL:(NSURL *)url { + [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil]; } -- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder { - [self setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil]; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil]; } -- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { - [self setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil]; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil]; } -- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock { - [self setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock]; +- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock]; } -- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock { - [self setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock]; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock]; } -- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { - [self setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock]; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock]; } -- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock { +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock { [self cancelCurrentImageLoad]; objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); self.image = placeholder; @@ -49,7 +49,7 @@ static char imageURLKey; if (url) { __weak UIImageView *wself = self; - id operation = [SDWebImageManager.sharedManager downloadWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) { + id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (!wself) return; dispatch_main_sync_safe(^{ if (!wself) return; @@ -63,28 +63,33 @@ static char imageURLKey; } } if (completedBlock && finished) { - completedBlock(image, error, cacheType); + completedBlock(image, error, cacheType, url); } }); }]; [self setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"]; + } else { + dispatch_main_async_safe(^{ + NSError *error = [NSError errorWithDomain:@"SDWebImageErrorDomain" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; + if (completedBlock) { + completedBlock(nil, error, SDImageCacheTypeNone, url); + } + }); } } -- (NSURL *)imageURL; -{ +- (NSURL *)imageURL { return objc_getAssociatedObject(self, &imageURLKey); } -- (void)setAnimationImagesWithURLs:(NSArray *)arrayOfURLs -{ +- (void)setAnimationImagesWithURLs:(NSArray *)arrayOfURLs { [self cancelCurrentAnimationImagesLoad]; __weak UIImageView *wself = self; NSMutableArray *operationsArray = [[NSMutableArray alloc] init]; for (NSURL *logoImageURL in arrayOfURLs) { - id operation = [SDWebImageManager.sharedManager downloadWithURL:logoImageURL options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) { + id operation = [SDWebImageManager.sharedManager downloadImageWithURL:logoImageURL options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (!wself) return; dispatch_main_sync_safe(^{ __strong UIImageView *sself = wself; @@ -117,3 +122,55 @@ static char imageURLKey; } @end + + +@implementation UIImageView (WebCacheDeprecated) + +- (void)setImageWithURL:(NSURL *)url { + [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil]; +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil]; +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil]; +} + +- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; + +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; + +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; + +} + +@end