From 81df4611a1fdcdadf8a696727ec999eec72bc4f5 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 06:54:38 +0300 Subject: [PATCH 01/19] Added FLAnimatedImage as submodule --- .gitmodules | 3 +++ Vendors/FLAnimatedImage | 1 + 2 files changed, 4 insertions(+) create mode 160000 Vendors/FLAnimatedImage diff --git a/.gitmodules b/.gitmodules index ce6396d4..c3be261d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "Vendors/libwebp"] path = Vendors/libwebp url = https://github.com/webmproject/libwebp +[submodule "Vendors/FLAnimatedImage"] + path = Vendors/FLAnimatedImage + url = git@github.com:Flipboard/FLAnimatedImage.git diff --git a/Vendors/FLAnimatedImage b/Vendors/FLAnimatedImage new file mode 160000 index 00000000..25307796 --- /dev/null +++ b/Vendors/FLAnimatedImage @@ -0,0 +1 @@ +Subproject commit 25307796cfcf66cb5b98774e050e93f64e0f2cde From b4659f764842063809819ce45091d2f31d3213f7 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 07:01:16 +0300 Subject: [PATCH 02/19] Added FLAnimatedImage to the project. Had to bump the deployment target to 6.0 since FLAnimatedImage only supports iOS 6 and later. --- SDWebImage.xcodeproj/project.pbxproj | 53 ++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/SDWebImage.xcodeproj/project.pbxproj b/SDWebImage.xcodeproj/project.pbxproj index 49f0d811..b2c77227 100644 --- a/SDWebImage.xcodeproj/project.pbxproj +++ b/SDWebImage.xcodeproj/project.pbxproj @@ -271,6 +271,18 @@ 438096731CDFC08F00DC626B /* MKAnnotationView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 535699B515113E7300A4C397 /* MKAnnotationView+WebCache.m */; }; 438096741CDFC09C00DC626B /* UIImage+WebP.h in Headers */ = {isa = PBXBuildFile; fileRef = 53EDFB911762547C00698166 /* UIImage+WebP.h */; settings = {ATTRIBUTES = (Public, ); }; }; 438096751CDFC0A100DC626B /* UIImage+WebP.m in Sources */ = {isa = PBXBuildFile; fileRef = 53EDFB921762547C00698166 /* UIImage+WebP.m */; }; + 43CE75761CFE9427006C64D0 /* FLAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE75491CFE9427006C64D0 /* FLAnimatedImage.h */; }; + 43CE75771CFE9427006C64D0 /* FLAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE75491CFE9427006C64D0 /* FLAnimatedImage.h */; }; + 43CE75781CFE9427006C64D0 /* FLAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE75491CFE9427006C64D0 /* FLAnimatedImage.h */; }; + 43CE75791CFE9427006C64D0 /* FLAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 43CE754A1CFE9427006C64D0 /* FLAnimatedImage.m */; }; + 43CE757A1CFE9427006C64D0 /* FLAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 43CE754A1CFE9427006C64D0 /* FLAnimatedImage.m */; }; + 43CE757B1CFE9427006C64D0 /* FLAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 43CE754A1CFE9427006C64D0 /* FLAnimatedImage.m */; }; + 43CE757C1CFE9427006C64D0 /* FLAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE754B1CFE9427006C64D0 /* FLAnimatedImageView.h */; }; + 43CE757D1CFE9427006C64D0 /* FLAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE754B1CFE9427006C64D0 /* FLAnimatedImageView.h */; }; + 43CE757E1CFE9427006C64D0 /* FLAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE754B1CFE9427006C64D0 /* FLAnimatedImageView.h */; }; + 43CE757F1CFE9427006C64D0 /* FLAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 43CE754C1CFE9427006C64D0 /* FLAnimatedImageView.m */; }; + 43CE75801CFE9427006C64D0 /* FLAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 43CE754C1CFE9427006C64D0 /* FLAnimatedImageView.m */; }; + 43CE75811CFE9427006C64D0 /* FLAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 43CE754C1CFE9427006C64D0 /* FLAnimatedImageView.m */; }; 4A2CAE041AB4BB5400B6BC39 /* SDWebImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A2CAE031AB4BB5400B6BC39 /* SDWebImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4A2CAE181AB4BB6400B6BC39 /* SDWebImageCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 53922D88148C56230056699D /* SDWebImageCompat.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4A2CAE191AB4BB6400B6BC39 /* SDWebImageCompat.m in Sources */ = {isa = PBXBuildFile; fileRef = 5340674F167780C40042B59E /* SDWebImageCompat.m */; }; @@ -341,6 +353,10 @@ /* Begin PBXFileReference section */ 00733A4C1BC487C000A5A117 /* SDWebImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 43CE75491CFE9427006C64D0 /* FLAnimatedImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLAnimatedImage.h; sourceTree = ""; }; + 43CE754A1CFE9427006C64D0 /* FLAnimatedImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLAnimatedImage.m; sourceTree = ""; }; + 43CE754B1CFE9427006C64D0 /* FLAnimatedImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLAnimatedImageView.h; sourceTree = ""; }; + 43CE754C1CFE9427006C64D0 /* FLAnimatedImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLAnimatedImageView.m; sourceTree = ""; }; 4A2CADFF1AB4BB5300B6BC39 /* SDWebImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4A2CAE021AB4BB5400B6BC39 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4A2CAE031AB4BB5400B6BC39 /* SDWebImage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImage.h; sourceTree = ""; }; @@ -487,6 +503,26 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 43CE75451CFE9427006C64D0 /* FLAnimatedImage */ = { + isa = PBXGroup; + children = ( + 43CE75481CFE9427006C64D0 /* FLAnimatedImage */, + ); + name = FLAnimatedImage; + path = Vendors/FLAnimatedImage; + sourceTree = ""; + }; + 43CE75481CFE9427006C64D0 /* FLAnimatedImage */ = { + isa = PBXGroup; + children = ( + 43CE75491CFE9427006C64D0 /* FLAnimatedImage.h */, + 43CE754A1CFE9427006C64D0 /* FLAnimatedImage.m */, + 43CE754B1CFE9427006C64D0 /* FLAnimatedImageView.h */, + 43CE754C1CFE9427006C64D0 /* FLAnimatedImageView.m */, + ); + path = FLAnimatedImage; + sourceTree = ""; + }; 4A2CAE001AB4BB5300B6BC39 /* WebImage */ = { isa = PBXGroup; children = ( @@ -528,6 +564,7 @@ 53922D71148C55820056699D /* Frameworks */ = { isa = PBXGroup; children = ( + 43CE75451CFE9427006C64D0 /* FLAnimatedImage */, DA577C121998E60B007367ED /* libwebp */, 53FB893F14D35D1A0020B787 /* CoreGraphics.framework */, 53922D72148C55820056699D /* Foundation.framework */, @@ -778,8 +815,10 @@ 431738D41CDFC8A40008FEB9 /* alphai.h in Headers */, 431739581CDFC8B70008FEB9 /* format_constants.h in Headers */, 431739491CDFC8B20008FEB9 /* rescaler.h in Headers */, + 43CE75781CFE9427006C64D0 /* FLAnimatedImage.h in Headers */, 431739161CDFC8AA0008FEB9 /* yuv.h in Headers */, 00733A6E1BC4880E00A5A117 /* UIImage+MultiFormat.h in Headers */, + 43CE757E1CFE9427006C64D0 /* FLAnimatedImageView.h in Headers */, 431738DD1CDFC8A40008FEB9 /* vp8i.h in Headers */, 00733A6D1BC4880E00A5A117 /* UIImage+GIF.h in Headers */, 00733A651BC4880E00A5A117 /* SDWebImageDownloader.h in Headers */, @@ -796,6 +835,7 @@ files = ( 4317394F1CDFC8B70008FEB9 /* demux.h in Headers */, 431739211CDFC8B20008FEB9 /* endian_inl.h in Headers */, + 43CE757D1CFE9427006C64D0 /* FLAnimatedImageView.h in Headers */, 431739541CDFC8B70008FEB9 /* types.h in Headers */, 431738F51CDFC8AA0008FEB9 /* neon.h in Headers */, 431738C51CDFC8A30008FEB9 /* alphai.h in Headers */, @@ -821,6 +861,7 @@ 431739291CDFC8B20008FEB9 /* quant_levels.h in Headers */, 4317391C1CDFC8B20008FEB9 /* bit_reader_inl.h in Headers */, 4317392B1CDFC8B20008FEB9 /* quant_levels_dec.h in Headers */, + 43CE75771CFE9427006C64D0 /* FLAnimatedImage.h in Headers */, 4A2CAE2B1AB4BB7500B6BC39 /* UIButton+WebCache.h in Headers */, 4A2CAE251AB4BB7000B6BC39 /* SDWebImagePrefetcher.h in Headers */, 4A2CAE371AB4BB7500B6BC39 /* UIView+WebCacheOperation.h in Headers */, @@ -889,8 +930,10 @@ 431738791CDFC2580008FEB9 /* alphai.h in Headers */, 431738C01CDFC2660008FEB9 /* format_constants.h in Headers */, 431738B81CDFC2630008FEB9 /* rescaler.h in Headers */, + 43CE75761CFE9427006C64D0 /* FLAnimatedImage.h in Headers */, 4317389F1CDFC25E0008FEB9 /* yuv.h in Headers */, 438096721CDFC08200DC626B /* MKAnnotationView+WebCache.h in Headers */, + 43CE757C1CFE9427006C64D0 /* FLAnimatedImageView.h in Headers */, 431738821CDFC2580008FEB9 /* vp8i.h in Headers */, AB615303192DA24600A2D8E9 /* UIView+WebCacheOperation.h in Headers */, A18A6CC7172DC28500419892 /* UIImage+GIF.h in Headers */, @@ -1074,6 +1117,7 @@ 4317393C1CDFC8B20008FEB9 /* filters.c in Sources */, 431738DA1CDFC8A40008FEB9 /* quant.c in Sources */, 00733A591BC4880000A5A117 /* SDWebImageDecoder.m in Sources */, + 43CE75811CFE9427006C64D0 /* FLAnimatedImageView.m in Sources */, 00733A5F1BC4880000A5A117 /* UIImage+WebP.m in Sources */, 431739041CDFC8AA0008FEB9 /* dec_neon.c in Sources */, 431739441CDFC8B20008FEB9 /* quant_levels_dec.c in Sources */, @@ -1083,6 +1127,7 @@ 431739141CDFC8AA0008FEB9 /* upsampling_sse2.c in Sources */, 00733A5D1BC4880000A5A117 /* UIImage+GIF.m in Sources */, 431738DC1CDFC8A40008FEB9 /* vp8.c in Sources */, + 43CE757B1CFE9427006C64D0 /* FLAnimatedImage.m in Sources */, 00733A571BC4880000A5A117 /* SDImageCache.m in Sources */, 4317394A1CDFC8B20008FEB9 /* thread.c in Sources */, 431739051CDFC8AA0008FEB9 /* dec_sse2.c in Sources */, @@ -1118,6 +1163,7 @@ 431738F41CDFC8AA0008FEB9 /* lossless_sse2.c in Sources */, 431738EF1CDFC8AA0008FEB9 /* enc_sse2.c in Sources */, 431739301CDFC8B20008FEB9 /* thread.c in Sources */, + 43CE757A1CFE9427006C64D0 /* FLAnimatedImage.m in Sources */, 4A2CAE361AB4BB7500B6BC39 /* UIImageView+WebCache.m in Sources */, 431739221CDFC8B20008FEB9 /* filters.c in Sources */, 431738FB1CDFC8AA0008FEB9 /* yuv_mips32.c in Sources */, @@ -1155,6 +1201,7 @@ 4A2CAE341AB4BB7500B6BC39 /* UIImageView+HighlightedWebCache.m in Sources */, 431738F81CDFC8AA0008FEB9 /* upsampling_sse2.c in Sources */, 4A2CAE201AB4BB6C00B6BC39 /* SDImageCache.m in Sources */, + 43CE75801CFE9427006C64D0 /* FLAnimatedImageView.m in Sources */, 431738C81CDFC8A30008FEB9 /* frame.c in Sources */, 4317391A1CDFC8B20008FEB9 /* bit_reader.c in Sources */, 431738E81CDFC8AA0008FEB9 /* dec_neon.c in Sources */, @@ -1186,6 +1233,7 @@ 431738991CDFC25E0008FEB9 /* lossless_sse2.c in Sources */, 431738941CDFC25E0008FEB9 /* enc_sse2.c in Sources */, 431738B91CDFC2630008FEB9 /* thread.c in Sources */, + 43CE75791CFE9427006C64D0 /* FLAnimatedImage.m in Sources */, 5376130B155AD0D5005750A4 /* SDWebImageDownloader.m in Sources */, 431738AB1CDFC2630008FEB9 /* filters.c in Sources */, 431738A01CDFC25E0008FEB9 /* yuv_mips32.c in Sources */, @@ -1223,6 +1271,7 @@ 53EDFB8C17623F7C00698166 /* UIImage+MultiFormat.m in Sources */, 4317389D1CDFC25E0008FEB9 /* upsampling_sse2.c in Sources */, ABBE71A818C43B4D00B75E91 /* UIImageView+HighlightedWebCache.m in Sources */, + 43CE757F1CFE9427006C64D0 /* FLAnimatedImageView.m in Sources */, 4317387C1CDFC2580008FEB9 /* frame.c in Sources */, 431738A31CDFC2630008FEB9 /* bit_reader.c in Sources */, 4317388D1CDFC25E0008FEB9 /* dec_neon.c in Sources */, @@ -1396,7 +1445,7 @@ GCC_WARN_UNUSED_PARAMETER = NO; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = Vendors/libwebp/src; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; RUN_CLANG_STATIC_ANALYZER = YES; @@ -1451,7 +1500,7 @@ GCC_WARN_UNUSED_PARAMETER = NO; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = Vendors/libwebp/src; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; OTHER_LDFLAGS = "-ObjC"; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; From e775b444ef82f47a13ec456616f2cc078e6ac9c5 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 09:35:36 +0300 Subject: [PATCH 03/19] Extended the SDImageCache `queryDiskCacheForKey:done:` so it also returns the NSData (we will need it later for the GIF images). - had to add an NSData param to `SDWebImageQueryCompletedBlock`, so to make it simpler see this change for users, renamed the block type to `SDCacheQueryCompletedBlock` - pass the NSData when getting the image from disk cache --- SDWebImage/SDImageCache.h | 4 ++-- SDWebImage/SDImageCache.m | 9 +++++---- SDWebImage/SDWebImageManager.m | 35 +++++++++++++++------------------- 3 files changed, 22 insertions(+), 26 deletions(-) diff --git a/SDWebImage/SDImageCache.h b/SDWebImage/SDImageCache.h index 36293ea8..8aecfa1f 100644 --- a/SDWebImage/SDImageCache.h +++ b/SDWebImage/SDImageCache.h @@ -24,7 +24,7 @@ typedef NS_ENUM(NSInteger, SDImageCacheType) { SDImageCacheTypeMemory }; -typedef void(^SDWebImageQueryCompletedBlock)(UIImage *image, SDImageCacheType cacheType); +typedef void(^SDCacheQueryCompletedBlock)(UIImage *image, NSData *data, SDImageCacheType cacheType); typedef void(^SDWebImageCheckCacheCompletionBlock)(BOOL isInCache); @@ -148,7 +148,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot * * @param key The unique key used to store the wanted image */ -- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDWebImageQueryCompletedBlock)doneBlock; +- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDCacheQueryCompletedBlock)doneBlock; /** * Query the memory cache synchronously. diff --git a/SDWebImage/SDImageCache.m b/SDWebImage/SDImageCache.m index 9e994d82..b8073cbc 100644 --- a/SDWebImage/SDImageCache.m +++ b/SDWebImage/SDImageCache.m @@ -385,20 +385,20 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { return SDScaledImageForKey(key, image); } -- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDWebImageQueryCompletedBlock)doneBlock { +- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDCacheQueryCompletedBlock)doneBlock { if (!doneBlock) { return nil; } if (!key) { - doneBlock(nil, SDImageCacheTypeNone); + doneBlock(nil, nil, SDImageCacheTypeNone); return nil; } // First check the in-memory cache... UIImage *image = [self imageFromMemoryCacheForKey:key]; if (image) { - doneBlock(image, SDImageCacheTypeMemory); + doneBlock(image, nil, SDImageCacheTypeMemory); return nil; } @@ -409,6 +409,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { } @autoreleasepool { + NSData *diskData = [self diskImageDataBySearchingAllPathsForKey:key]; UIImage *diskImage = [self diskImageForKey:key]; if (diskImage && self.shouldCacheImagesInMemory) { NSUInteger cost = SDCacheCostForImage(diskImage); @@ -416,7 +417,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { } dispatch_async(dispatch_get_main_queue(), ^{ - doneBlock(diskImage, SDImageCacheTypeDisk); + doneBlock(diskImage, diskData, SDImageCacheTypeDisk); }); } }); diff --git a/SDWebImage/SDWebImageManager.m b/SDWebImage/SDWebImageManager.m index bba2d124..8004fad9 100644 --- a/SDWebImage/SDWebImageManager.m +++ b/SDWebImage/SDWebImageManager.m @@ -154,7 +154,7 @@ } NSString *key = [self cacheKeyForURL:url]; - operation.cacheOperation = [self.imageCache queryDiskCacheForKey:key done:^(UIImage *image, SDImageCacheType cacheType) { + operation.cacheOperation = [self.imageCache queryDiskCacheForKey:key done:^(UIImage *cachedImage, NSData *cachedData, SDImageCacheType cacheType) { if (operation.isCancelled) { @synchronized (self.runningOperations) { [self.runningOperations removeObject:operation]; @@ -163,12 +163,12 @@ return; } - if ((!image || options & SDWebImageRefreshCached) && (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url])) { - if (image && options & SDWebImageRefreshCached) { + if ((!cachedImage || options & SDWebImageRefreshCached) && (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url])) { + if (cachedImage && options & SDWebImageRefreshCached) { dispatch_main_sync_safe(^{ // If image was found in the cache but 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, url); + completedBlock(cachedImage, nil, cacheType, YES, url); }); } @@ -181,20 +181,19 @@ if (options & SDWebImageHandleCookies) downloaderOptions |= SDWebImageDownloaderHandleCookies; if (options & SDWebImageAllowInvalidSSLCertificates) downloaderOptions |= SDWebImageDownloaderAllowInvalidSSLCertificates; if (options & SDWebImageHighPriority) downloaderOptions |= SDWebImageDownloaderHighPriority; - if (image && options & SDWebImageRefreshCached) { + if (cachedImage && options & SDWebImageRefreshCached) { // force progressive off if image already cached but forced refreshing downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload; // ignore image read from NSURLCache if image if cached but force refreshing downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse; } - id subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(UIImage *downloadedImage, NSData *data, NSError *error, BOOL finished) { + id subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(UIImage *downloadedImage, NSData *downloadedData, NSError *error, BOOL finished) { __strong __typeof(weakOperation) strongOperation = weakOperation; if (!strongOperation || strongOperation.isCancelled) { // Do nothing if the operation was cancelled // See #699 for more details // if we would call the completedBlock, there could be a race condition between this block and another completedBlock for the same object, so if this one is called second, we will overwrite the new data - } - else if (error) { + } else if (error) { dispatch_main_sync_safe(^{ if (strongOperation && !strongOperation.isCancelled) { completedBlock(nil, error, SDImageCacheTypeNone, finished, url); @@ -222,16 +221,15 @@ BOOL cacheOnDisk = !(options & SDWebImageCacheMemoryOnly); - if (options & SDWebImageRefreshCached && image && !downloadedImage) { + if (options & SDWebImageRefreshCached && cachedImage && !downloadedImage) { // Image refresh hit the NSURLCache cache, do not call the completion block - } - else if (downloadedImage && (!downloadedImage.images || (options & SDWebImageTransformAnimatedImage)) && [self.delegate respondsToSelector:@selector(imageManager:transformDownloadedImage:withURL:)]) { + } else if (downloadedImage && (!downloadedImage.images || (options & SDWebImageTransformAnimatedImage)) && [self.delegate respondsToSelector:@selector(imageManager:transformDownloadedImage:withURL:)]) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ UIImage *transformedImage = [self.delegate imageManager:self transformDownloadedImage:downloadedImage withURL:url]; if (transformedImage && finished) { BOOL imageWasTransformed = ![transformedImage isEqual:downloadedImage]; - [self.imageCache storeImage:transformedImage recalculateFromImage:imageWasTransformed imageData:(imageWasTransformed ? nil : data) forKey:key toDisk:cacheOnDisk]; + [self.imageCache storeImage:transformedImage recalculateFromImage:imageWasTransformed imageData:(imageWasTransformed ? nil : downloadedData) forKey:key toDisk:cacheOnDisk]; } dispatch_main_sync_safe(^{ @@ -240,10 +238,9 @@ } }); }); - } - else { + } else { if (downloadedImage && finished) { - [self.imageCache storeImage:downloadedImage recalculateFromImage:NO imageData:data forKey:key toDisk:cacheOnDisk]; + [self.imageCache storeImage:downloadedImage recalculateFromImage:NO imageData:downloadedData forKey:key toDisk:cacheOnDisk]; } dispatch_main_sync_safe(^{ @@ -272,19 +269,17 @@ } } }; - } - else if (image) { + } else if (cachedImage) { dispatch_main_sync_safe(^{ __strong __typeof(weakOperation) strongOperation = weakOperation; if (strongOperation && !strongOperation.isCancelled) { - completedBlock(image, nil, cacheType, YES, url); + completedBlock(cachedImage, nil, cacheType, YES, url); } }); @synchronized (self.runningOperations) { [self.runningOperations removeObject:operation]; } - } - else { + } else { // Image not in cache and download disallowed by delegate dispatch_main_sync_safe(^{ __strong __typeof(weakOperation) strongOperation = weakOperation; From aecb13d4210f5a91669fa5003e538f47dd8f05cb Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 09:40:36 +0300 Subject: [PATCH 04/19] Extended the SDWebImageManager `loadImageWithURL:options:progress:completed:` so it also returns the NSData (we will need it later for the GIF images). - had to add an NSData param to `SDWebImageCompletionWithFinishedBlock `, so to make it simpler see this change for users, renamed the block type to `SDInternalCompletionBlock` - pass the NSData from the ImageCache or the Downloader - updated all classes using this method with the new signature --- SDWebImage/MKAnnotationView+WebCache.m | 2 +- SDWebImage/SDWebImageManager.h | 4 ++-- SDWebImage/SDWebImageManager.m | 20 ++++++++++---------- SDWebImage/SDWebImagePrefetcher.m | 2 +- SDWebImage/UIButton+WebCache.m | 4 ++-- SDWebImage/UIImageView+HighlightedWebCache.m | 2 +- SDWebImage/UIImageView+WebCache.m | 4 ++-- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/SDWebImage/MKAnnotationView+WebCache.m b/SDWebImage/MKAnnotationView+WebCache.m index 7e982ede..171880fa 100644 --- a/SDWebImage/MKAnnotationView+WebCache.m +++ b/SDWebImage/MKAnnotationView+WebCache.m @@ -46,7 +46,7 @@ static char imageURLKey; if (url) { __weak __typeof(self)wself = self; - id operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + id operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (!wself) return; dispatch_main_sync_safe(^{ __strong MKAnnotationView *sself = wself; diff --git a/SDWebImage/SDWebImageManager.h b/SDWebImage/SDWebImageManager.h index 7edfc74c..95224d44 100644 --- a/SDWebImage/SDWebImageManager.h +++ b/SDWebImage/SDWebImageManager.h @@ -92,7 +92,7 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) { typedef void(^SDWebImageCompletionBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL); -typedef void(^SDWebImageCompletionWithFinishedBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL); +typedef void(^SDInternalCompletionBlock)(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL); typedef NSString *(^SDWebImageCacheKeyFilterBlock)(NSURL *url); @@ -212,7 +212,7 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; - (id )loadImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock - completed:(SDWebImageCompletionWithFinishedBlock)completedBlock; + completed:(SDInternalCompletionBlock)completedBlock; /** * Saves image to cache for given URL diff --git a/SDWebImage/SDWebImageManager.m b/SDWebImage/SDWebImageManager.m index 8004fad9..20bcb65c 100644 --- a/SDWebImage/SDWebImageManager.m +++ b/SDWebImage/SDWebImageManager.m @@ -116,9 +116,9 @@ } - (id )loadImageWithURL:(NSURL *)url - options:(SDWebImageOptions)options - progress:(SDWebImageDownloaderProgressBlock)progressBlock - completed:(SDWebImageCompletionWithFinishedBlock)completedBlock { + options:(SDWebImageOptions)options + progress:(SDWebImageDownloaderProgressBlock)progressBlock + completed:(SDInternalCompletionBlock)completedBlock { // Invoking this method without a completedBlock is pointless NSAssert(completedBlock != nil, @"If you mean to prefetch the image, use -[SDWebImagePrefetcher prefetchURLs] instead"); @@ -144,7 +144,7 @@ if (url.absoluteString.length == 0 || (!(options & SDWebImageRetryFailed) && isFailedUrl)) { dispatch_main_sync_safe(^{ NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil]; - completedBlock(nil, error, SDImageCacheTypeNone, YES, url); + completedBlock(nil, nil, error, SDImageCacheTypeNone, YES, url); }); return operation; } @@ -168,7 +168,7 @@ dispatch_main_sync_safe(^{ // If image was found in the cache but 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(cachedImage, nil, cacheType, YES, url); + completedBlock(cachedImage, cachedData, nil, cacheType, YES, url); }); } @@ -196,7 +196,7 @@ } else if (error) { dispatch_main_sync_safe(^{ if (strongOperation && !strongOperation.isCancelled) { - completedBlock(nil, error, SDImageCacheTypeNone, finished, url); + completedBlock(nil, nil, error, SDImageCacheTypeNone, finished, url); } }); @@ -234,7 +234,7 @@ dispatch_main_sync_safe(^{ if (strongOperation && !strongOperation.isCancelled) { - completedBlock(transformedImage, nil, SDImageCacheTypeNone, finished, url); + completedBlock(transformedImage, downloadedData, nil, SDImageCacheTypeNone, finished, url); } }); }); @@ -245,7 +245,7 @@ dispatch_main_sync_safe(^{ if (strongOperation && !strongOperation.isCancelled) { - completedBlock(downloadedImage, nil, SDImageCacheTypeNone, finished, url); + completedBlock(downloadedImage, downloadedData, nil, SDImageCacheTypeNone, finished, url); } }); } @@ -273,7 +273,7 @@ dispatch_main_sync_safe(^{ __strong __typeof(weakOperation) strongOperation = weakOperation; if (strongOperation && !strongOperation.isCancelled) { - completedBlock(cachedImage, nil, cacheType, YES, url); + completedBlock(cachedImage, cachedData, nil, cacheType, YES, url); } }); @synchronized (self.runningOperations) { @@ -284,7 +284,7 @@ dispatch_main_sync_safe(^{ __strong __typeof(weakOperation) strongOperation = weakOperation; if (strongOperation && !weakOperation.isCancelled) { - completedBlock(nil, nil, SDImageCacheTypeNone, YES, url); + completedBlock(nil, nil, nil, SDImageCacheTypeNone, YES, url); } }); @synchronized (self.runningOperations) { diff --git a/SDWebImage/SDWebImagePrefetcher.m b/SDWebImage/SDWebImagePrefetcher.m index 1dfddafd..b7876624 100644 --- a/SDWebImage/SDWebImagePrefetcher.m +++ b/SDWebImage/SDWebImagePrefetcher.m @@ -57,7 +57,7 @@ - (void)startPrefetchingAtIndex:(NSUInteger)index { if (index >= self.prefetchURLs.count) return; self.requestedCount++; - [self.manager loadImageWithURL:self.prefetchURLs[index] options:self.options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + [self.manager loadImageWithURL:self.prefetchURLs[index] options:self.options progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (!finished) return; self.finishedCount++; diff --git a/SDWebImage/UIButton+WebCache.m b/SDWebImage/UIButton+WebCache.m index fd296506..10a1c066 100644 --- a/SDWebImage/UIButton+WebCache.m +++ b/SDWebImage/UIButton+WebCache.m @@ -69,7 +69,7 @@ static char imageURLStorageKey; self.imageURLStorage[@(state)] = url; __weak __typeof(self)wself = self; - id operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + id operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (!wself) return; dispatch_main_sync_safe(^{ __strong UIButton *sself = wself; @@ -117,7 +117,7 @@ static char imageURLStorageKey; if (url) { __weak __typeof(self)wself = self; - id operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + id operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (!wself) return; dispatch_main_sync_safe(^{ __strong UIButton *sself = wself; diff --git a/SDWebImage/UIImageView+HighlightedWebCache.m b/SDWebImage/UIImageView+HighlightedWebCache.m index 9cc10252..716b37f2 100644 --- a/SDWebImage/UIImageView+HighlightedWebCache.m +++ b/SDWebImage/UIImageView+HighlightedWebCache.m @@ -34,7 +34,7 @@ if (url) { __weak __typeof(self)wself = self; - id operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + id operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (!wself) return; dispatch_main_sync_safe (^ { diff --git a/SDWebImage/UIImageView+WebCache.m b/SDWebImage/UIImageView+WebCache.m index a86e4c06..616cc2da 100644 --- a/SDWebImage/UIImageView+WebCache.m +++ b/SDWebImage/UIImageView+WebCache.m @@ -59,7 +59,7 @@ static char TAG_ACTIVITY_SHOW; } __weak __typeof(self)wself = self; - id operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + id operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { [wself removeActivityIndicator]; if (!wself) return; dispatch_main_sync_safe(^{ @@ -113,7 +113,7 @@ static char TAG_ACTIVITY_SHOW; NSMutableArray *operationsArray = [[NSMutableArray alloc] init]; for (NSURL *logoImageURL in arrayOfURLs) { - id operation = [SDWebImageManager.sharedManager loadImageWithURL:logoImageURL options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + id operation = [SDWebImageManager.sharedManager loadImageWithURL:logoImageURL options:0 progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (!wself) return; dispatch_main_sync_safe(^{ __strong UIImageView *sself = wself; From 8f4a9dae2de0e803b53c8419bc6a739b7e2b9bb3 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 09:41:44 +0300 Subject: [PATCH 05/19] For consistency with the previous change, also renamed `SDWebImageCompletionBlock` to `SDExternalCompletionBlock` --- SDWebImage/MKAnnotationView+WebCache.h | 6 +++--- SDWebImage/MKAnnotationView+WebCache.m | 6 +++--- SDWebImage/SDWebImageManager.h | 2 +- SDWebImage/UIButton+WebCache.h | 12 ++++++------ SDWebImage/UIButton+WebCache.m | 12 ++++++------ SDWebImage/UIImageView+HighlightedWebCache.h | 6 +++--- SDWebImage/UIImageView+HighlightedWebCache.m | 6 +++--- SDWebImage/UIImageView+WebCache.h | 10 +++++----- SDWebImage/UIImageView+WebCache.m | 10 +++++----- 9 files changed, 35 insertions(+), 35 deletions(-) diff --git a/SDWebImage/MKAnnotationView+WebCache.h b/SDWebImage/MKAnnotationView+WebCache.h index 175b13fb..b0df29c4 100644 --- a/SDWebImage/MKAnnotationView+WebCache.h +++ b/SDWebImage/MKAnnotationView+WebCache.h @@ -66,7 +66,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock; /** * Set the imageView `image` with an `url`, placeholder. @@ -81,7 +81,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock; /** * Set the imageView `image` with an `url`, placeholder and custom options. @@ -97,7 +97,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock; /** * Cancel the current download diff --git a/SDWebImage/MKAnnotationView+WebCache.m b/SDWebImage/MKAnnotationView+WebCache.m index 171880fa..398183f4 100644 --- a/SDWebImage/MKAnnotationView+WebCache.m +++ b/SDWebImage/MKAnnotationView+WebCache.m @@ -30,15 +30,15 @@ static char imageURLKey; [self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:nil]; } -- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock { +- (void)sd_setImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock { [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:completedBlock]; } -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock { +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock { [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:completedBlock]; } -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock { [self sd_cancelCurrentImageLoad]; objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); diff --git a/SDWebImage/SDWebImageManager.h b/SDWebImage/SDWebImageManager.h index 95224d44..17581703 100644 --- a/SDWebImage/SDWebImageManager.h +++ b/SDWebImage/SDWebImageManager.h @@ -90,7 +90,7 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) { SDWebImageAvoidAutoSetImage = 1 << 11 }; -typedef void(^SDWebImageCompletionBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL); +typedef void(^SDExternalCompletionBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL); typedef void(^SDInternalCompletionBlock)(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL); diff --git a/SDWebImage/UIButton+WebCache.h b/SDWebImage/UIButton+WebCache.h index fa908bb6..033e92e9 100644 --- a/SDWebImage/UIButton+WebCache.h +++ b/SDWebImage/UIButton+WebCache.h @@ -73,7 +73,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDExternalCompletionBlock)completedBlock; /** * Set the imageView `image` with an `url`, placeholder. @@ -89,7 +89,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock; /** * Set the imageView `image` with an `url`, placeholder and custom options. @@ -106,7 +106,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock; /** * Set the backgroundImageView `image` with an `url`. @@ -155,7 +155,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock; +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDExternalCompletionBlock)completedBlock; /** * Set the backgroundImageView `image` with an `url`, placeholder. @@ -171,7 +171,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock; +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock; /** * Set the backgroundImageView `image` with an `url`, placeholder and custom options. @@ -187,7 +187,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock; /** * Cancel the current image download diff --git a/SDWebImage/UIButton+WebCache.m b/SDWebImage/UIButton+WebCache.m index 10a1c066..09a8ef19 100644 --- a/SDWebImage/UIButton+WebCache.m +++ b/SDWebImage/UIButton+WebCache.m @@ -40,15 +40,15 @@ static char imageURLStorageKey; [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil]; } -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock { +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDExternalCompletionBlock)completedBlock { [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock]; } -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock { +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock { [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock]; } -- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock { [self setImage:placeholder forState:state]; [self sd_cancelImageLoadForState:state]; @@ -102,15 +102,15 @@ static char imageURLStorageKey; [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil]; } -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock { +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDExternalCompletionBlock)completedBlock { [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock]; } -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock { +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock { [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock]; } -- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock { [self sd_cancelBackgroundImageLoadForState:state]; [self setBackgroundImage:placeholder forState:state]; diff --git a/SDWebImage/UIImageView+HighlightedWebCache.h b/SDWebImage/UIImageView+HighlightedWebCache.h index bc94f7b0..3bf0876f 100644 --- a/SDWebImage/UIImageView+HighlightedWebCache.h +++ b/SDWebImage/UIImageView+HighlightedWebCache.h @@ -46,7 +46,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock; +- (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock; /** * Set the imageView `highlightedImage` with an `url` and custom options. @@ -61,7 +61,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; +- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock; /** * Set the imageView `highlightedImage` with an `url` and custom options. @@ -77,7 +77,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock; +- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock; /** * Cancel the current download diff --git a/SDWebImage/UIImageView+HighlightedWebCache.m b/SDWebImage/UIImageView+HighlightedWebCache.m index 716b37f2..dd752b8d 100644 --- a/SDWebImage/UIImageView+HighlightedWebCache.m +++ b/SDWebImage/UIImageView+HighlightedWebCache.m @@ -21,15 +21,15 @@ [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil]; } -- (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock { +- (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock { [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:completedBlock]; } -- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { +- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock { [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:completedBlock]; } -- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock { +- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock { [self sd_cancelCurrentHighlightedImageLoad]; if (url) { diff --git a/SDWebImage/UIImageView+WebCache.h b/SDWebImage/UIImageView+WebCache.h index b057aa7f..f49d78c8 100644 --- a/SDWebImage/UIImageView+WebCache.h +++ b/SDWebImage/UIImageView+WebCache.h @@ -95,7 +95,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock; /** * Set the imageView `image` with an `url`, placeholder. @@ -110,7 +110,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock; /** * Set the imageView `image` with an `url`, placeholder and custom options. @@ -126,7 +126,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock; /** * Set the imageView `image` with an `url`, placeholder and custom options. @@ -143,7 +143,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock; /** * Set the imageView `image` with an `url` and optionally a placeholder image. @@ -160,7 +160,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock; +- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock; /** * Download an array of images and starts them in an animation loop diff --git a/SDWebImage/UIImageView+WebCache.m b/SDWebImage/UIImageView+WebCache.m index 616cc2da..f2a42ec6 100644 --- a/SDWebImage/UIImageView+WebCache.m +++ b/SDWebImage/UIImageView+WebCache.m @@ -29,19 +29,19 @@ static char TAG_ACTIVITY_SHOW; [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil]; } -- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock { +- (void)sd_setImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock { [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock]; } -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock { +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock { [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock]; } -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock { [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock]; } -- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock { +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock { [self sd_cancelCurrentImageLoad]; objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); @@ -95,7 +95,7 @@ static char TAG_ACTIVITY_SHOW; } } -- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock { +- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock { NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:url]; UIImage *lastPreviousCachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:key]; From debc0d482763f4a48f896a16cec10fc2d90231c0 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 09:42:39 +0300 Subject: [PATCH 06/19] Exposed the activity indicator methods from UIImageView+WebView so we can use them in a future category --- SDWebImage/UIImageView+WebCache.h | 5 +++++ SDWebImage/UIImageView+WebCache.m | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/SDWebImage/UIImageView+WebCache.h b/SDWebImage/UIImageView+WebCache.h index f49d78c8..44cd2d76 100644 --- a/SDWebImage/UIImageView+WebCache.h +++ b/SDWebImage/UIImageView+WebCache.h @@ -188,4 +188,9 @@ */ - (void)setIndicatorStyle:(UIActivityIndicatorViewStyle)style; +- (BOOL)showActivityIndicatorView; +- (void)addActivityIndicator; +- (void)removeActivityIndicator; + + @end diff --git a/SDWebImage/UIImageView+WebCache.m b/SDWebImage/UIImageView+WebCache.m index f2a42ec6..f0823f17 100644 --- a/SDWebImage/UIImageView+WebCache.m +++ b/SDWebImage/UIImageView+WebCache.m @@ -155,11 +155,11 @@ static char TAG_ACTIVITY_SHOW; objc_setAssociatedObject(self, &TAG_ACTIVITY_INDICATOR, activityIndicator, OBJC_ASSOCIATION_RETAIN); } -- (void)setShowActivityIndicatorView:(BOOL)show{ +- (void)setShowActivityIndicatorView:(BOOL)show { objc_setAssociatedObject(self, &TAG_ACTIVITY_SHOW, @(show), OBJC_ASSOCIATION_RETAIN); } -- (BOOL)showActivityIndicatorView{ +- (BOOL)showActivityIndicatorView { return [objc_getAssociatedObject(self, &TAG_ACTIVITY_SHOW) boolValue]; } From 9ea1602157a6719dd2ea71172a48628eb9f7e5c3 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 09:43:53 +0300 Subject: [PATCH 07/19] Changed the current internal GIF implementation. We will only return an UIImage with a single animated frame (basically a static image). We do set it in the images array so we can distinguish between those and real static images. Dropped all other GIF code. --- SDWebImage/UIImage+GIF.h | 10 ++- SDWebImage/UIImage+GIF.m | 141 ++++----------------------------------- 2 files changed, 20 insertions(+), 131 deletions(-) diff --git a/SDWebImage/UIImage+GIF.h b/SDWebImage/UIImage+GIF.h index 084f4241..97a9893f 100755 --- a/SDWebImage/UIImage+GIF.h +++ b/SDWebImage/UIImage+GIF.h @@ -10,10 +10,14 @@ @interface UIImage (GIF) -+ (UIImage *)sd_animatedGIFNamed:(NSString *)name; - +/** + * Compatibility method - creates an animated UIImage from an NSData, it will only contain the 1st frame image + */ + (UIImage *)sd_animatedGIFWithData:(NSData *)data; -- (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size; +/** + * Checks if an UIImage instance is a GIF. Will use the `images` array + */ +- (BOOL)isGIF; @end diff --git a/SDWebImage/UIImage+GIF.m b/SDWebImage/UIImage+GIF.m index de45dd35..bf666113 100755 --- a/SDWebImage/UIImage+GIF.m +++ b/SDWebImage/UIImage+GIF.m @@ -8,6 +8,7 @@ #import "UIImage+GIF.h" #import +#import "objc/runtime.h" @implementation UIImage (GIF) @@ -20,142 +21,26 @@ size_t count = CGImageSourceGetCount(source); - UIImage *animatedImage; + UIImage *staticImage; if (count <= 1) { - animatedImage = [[UIImage alloc] initWithData:data]; - } - else { - NSMutableArray *images = [NSMutableArray array]; - - NSTimeInterval duration = 0.0f; - - for (size_t i = 0; i < count; i++) { - CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL); - if (!image) { - continue; - } - - duration += [self sd_frameDurationAtIndex:i source:source]; - - [images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]]; - - CGImageRelease(image); - } - - if (!duration) { - duration = (1.0f / 10.0f) * count; - } - - animatedImage = [UIImage animatedImageWithImages:images duration:duration]; + staticImage = [[UIImage alloc] initWithData:data]; + } else { + // we will only retrieve the 1st frame. the full GIF support is available via the FLAnimatedImageView category. + // this here is only code to allow drawing animated images as static ones + CGImageRef CGImage = CGImageSourceCreateImageAtIndex(source, 0, NULL); + UIImage *frameImage = [UIImage imageWithCGImage:CGImage scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]; + staticImage = [UIImage animatedImageWithImages:@[frameImage] duration:0.0f]; + CGImageRelease(CGImage); } CFRelease(source); - return animatedImage; + return staticImage; } -+ (float)sd_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source { - float frameDuration = 0.1f; - CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil); - NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties; - NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary]; - - NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime]; - if (delayTimeUnclampedProp) { - frameDuration = delayTimeUnclampedProp.floatValue; - } - else { - - NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime]; - if (delayTimeProp) { - frameDuration = delayTimeProp.floatValue; - } - } - - // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. - // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify - // a duration of <= 10 ms. See and - // for more information. - - if (frameDuration < 0.011f) { - frameDuration = 0.100f; - } - - CFRelease(cfFrameProperties); - return frameDuration; -} - -+ (UIImage *)sd_animatedGIFNamed:(NSString *)name { - CGFloat scale = [UIScreen mainScreen].scale; - - if (scale > 1.0f) { - NSString *retinaPath = [[NSBundle mainBundle] pathForResource:[name stringByAppendingString:@"@2x"] ofType:@"gif"]; - - NSData *data = [NSData dataWithContentsOfFile:retinaPath]; - - if (data) { - return [UIImage sd_animatedGIFWithData:data]; - } - - NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"]; - - data = [NSData dataWithContentsOfFile:path]; - - if (data) { - return [UIImage sd_animatedGIFWithData:data]; - } - - return [UIImage imageNamed:name]; - } - else { - NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"]; - - NSData *data = [NSData dataWithContentsOfFile:path]; - - if (data) { - return [UIImage sd_animatedGIFWithData:data]; - } - - return [UIImage imageNamed:name]; - } -} - -- (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size { - if (CGSizeEqualToSize(self.size, size) || CGSizeEqualToSize(size, CGSizeZero)) { - return self; - } - - CGSize scaledSize = size; - CGPoint thumbnailPoint = CGPointZero; - - CGFloat widthFactor = size.width / self.size.width; - CGFloat heightFactor = size.height / self.size.height; - CGFloat scaleFactor = (widthFactor > heightFactor) ? widthFactor : heightFactor; - scaledSize.width = self.size.width * scaleFactor; - scaledSize.height = self.size.height * scaleFactor; - - if (widthFactor > heightFactor) { - thumbnailPoint.y = (size.height - scaledSize.height) * 0.5; - } - else if (widthFactor < heightFactor) { - thumbnailPoint.x = (size.width - scaledSize.width) * 0.5; - } - - NSMutableArray *scaledImages = [NSMutableArray array]; - - for (UIImage *image in self.images) { - UIGraphicsBeginImageContextWithOptions(size, NO, 0.0); - - [image drawInRect:CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledSize.width, scaledSize.height)]; - UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); - - [scaledImages addObject:newImage]; - - UIGraphicsEndImageContext(); - } - - return [UIImage animatedImageWithImages:scaledImages duration:self.duration]; +- (BOOL)isGIF { + return (self.images != nil); } @end From ada86ab9396e678e66f71b395ca0c91ccd700790 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 09:45:13 +0300 Subject: [PATCH 08/19] Based on the previous change, we now can avoid the memory cache for GIFs, as the memory cache only holds UIImage instances and we need the NSData. Forced to load from disk if the image is a GIF --- SDWebImage/SDImageCache.m | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/SDWebImage/SDImageCache.m b/SDWebImage/SDImageCache.m index b8073cbc..f04b5af5 100644 --- a/SDWebImage/SDImageCache.m +++ b/SDWebImage/SDImageCache.m @@ -10,6 +10,7 @@ #import "SDWebImageDecoder.h" #import "UIImage+MultiFormat.h" #import +#import "UIImage+GIF.h" // See https://github.com/rs/SDWebImage/pull/1141 for discussion @interface AutoPurgeCache : NSCache @@ -398,7 +399,11 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { // First check the in-memory cache... UIImage *image = [self imageFromMemoryCacheForKey:key]; if (image) { - doneBlock(image, nil, SDImageCacheTypeMemory); + NSData *diskData = nil; + if ([image isGIF]) { + diskData = [self diskImageDataBySearchingAllPathsForKey:key]; + } + doneBlock(image, diskData, SDImageCacheTypeMemory); return nil; } From 32f4e4d234e84ecf06cff18454f70093401fa650 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 10:02:20 +0300 Subject: [PATCH 09/19] Updated the doc with the new completion type (SDWebImageManager loadImageWithURL) --- SDWebImage/SDWebImageManager.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/SDWebImage/SDWebImageManager.h b/SDWebImage/SDWebImageManager.h index 17581703..1f61598d 100644 --- a/SDWebImage/SDWebImageManager.h +++ b/SDWebImage/SDWebImageManager.h @@ -197,16 +197,18 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; * * This parameter is required. * - * 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. + * This block has no return value and takes the requested UIImage as first parameter and the NSData representation as second parameter. + * In case of error the image parameter is nil and the third parameter may contain an NSError. * - * The third parameter is an `SDImageCacheType` enum indicating if the image was retrieved from the local cache + * The forth parameter is an `SDImageCacheType` enum indicating if the image was retrieved from the local cache * or from the memory cache or from the network. * - * The last parameter is set to NO when the SDWebImageProgressiveDownload option is used and the image is + * The fith parameter is set to NO when the SDWebImageProgressiveDownload option is used and the image is * downloading. This block is thus called repeatedly with a partial image. When image is fully downloaded, the * block is called a last time with the full image and the last parameter set to YES. * + * The last parameter is the original image URL + * * @return Returns an NSObject conforming to SDWebImageOperation. Should be an instance of SDWebImageDownloaderOperation */ - (id )loadImageWithURL:(NSURL *)url From 881da8fbe06760203c569631c5ff6aa848bb0c5f Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 10:02:41 +0300 Subject: [PATCH 10/19] Corrected comment (was changed unintentionally). --- SDWebImage/MKAnnotationView+WebCache.h | 2 +- SDWebImage/UIImageView+WebCache.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SDWebImage/MKAnnotationView+WebCache.h b/SDWebImage/MKAnnotationView+WebCache.h index b0df29c4..8f87f2e3 100644 --- a/SDWebImage/MKAnnotationView+WebCache.h +++ b/SDWebImage/MKAnnotationView+WebCache.h @@ -18,7 +18,7 @@ * Get the current image URL. * * Note that because of the limitations of categories this property can get out of sync - * if you use sd_setImage: directly. + * if you use setImage: directly. */ - (NSURL *)sd_imageURL; diff --git a/SDWebImage/UIImageView+WebCache.h b/SDWebImage/UIImageView+WebCache.h index 44cd2d76..a6c73561 100644 --- a/SDWebImage/UIImageView+WebCache.h +++ b/SDWebImage/UIImageView+WebCache.h @@ -48,7 +48,7 @@ * Get the current image URL. * * Note that because of the limitations of categories this property can get out of sync - * if you use sd_setImage: directly. + * if you use setImage: directly. */ - (NSURL *)sd_imageURL; From c1451f28af5fffbf383fe610a4c7b1a83fd9d70a Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 10:05:16 +0300 Subject: [PATCH 11/19] Built a FLAnimatedImageView category that hooks this class to the SDWebImage system. It's very similar to UIImageView (WebCache). There are explicit methods for loading an animated image. --- .../FLAnimatedImageView+WebCache.h | 128 ++++++++++++++++++ .../FLAnimatedImageView+WebCache.m | 115 ++++++++++++++++ 2 files changed, 243 insertions(+) create mode 100644 SDWebImage/FLAnimatedImage/FLAnimatedImageView+WebCache.h create mode 100644 SDWebImage/FLAnimatedImage/FLAnimatedImageView+WebCache.m diff --git a/SDWebImage/FLAnimatedImage/FLAnimatedImageView+WebCache.h b/SDWebImage/FLAnimatedImage/FLAnimatedImageView+WebCache.h new file mode 100644 index 00000000..dfccad62 --- /dev/null +++ b/SDWebImage/FLAnimatedImage/FLAnimatedImageView+WebCache.h @@ -0,0 +1,128 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + + +#if COCOAPODS + @import FLAnimatedImage; +#else + #import "FLAnimatedImageView.h" +#endif + +#import "SDWebImageManager.h" + + +/** + * A category for the FLAnimatedImage imageView class that hooks it to the SDWebImage system. + * Very similar to the base class category (UIImageView (WebCache)) + */ +@interface FLAnimatedImageView (WebCache) + +/** + * 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. + */ +- (NSURL *)sd_imageURL; + +/** + * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images + * The download is asynchronous and cached. + * + * @param url The url for the image. + */ +- (void)sd_setAnimatedImageWithURL:(NSURL *)url; + +/** + * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images + * The download is asynchronous and cached. + * Uses a placeholder until the request finishes. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + */ +- (void)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; + +/** + * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images + * The download is asynchronous and cached. + * Uses a placeholder until the request finishes. + * + * @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)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; + +/** + * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images + * 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 retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setAnimatedImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock; + +/** + * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images + * The download is asynchronous and cached. + * Uses a placeholder until the request finishes. + * + * @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 retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock; + +/** + * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images + * The download is asynchronous and cached. + * Uses a placeholder until the request finishes. + * + * @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 retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock; + +/** + * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images + * The download is asynchronous and cached. + * Uses a placeholder until the request finishes. + * + * @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 retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock; + +/** + * Cancel the image load + */ +- (void)sd_cancelCurrentAnimatedImageLoad; + +@end diff --git a/SDWebImage/FLAnimatedImage/FLAnimatedImageView+WebCache.m b/SDWebImage/FLAnimatedImage/FLAnimatedImageView+WebCache.m new file mode 100644 index 00000000..3b90f053 --- /dev/null +++ b/SDWebImage/FLAnimatedImage/FLAnimatedImageView+WebCache.m @@ -0,0 +1,115 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + + +#import "FLAnimatedImageView+WebCache.h" +#import "objc/runtime.h" +#import "UIView+WebCacheOperation.h" +#import "NSData+ImageContentType.h" +#import "FLAnimatedImage.h" +#import "UIImageView+WebCache.h" + +static char imageURLKey; + + +@implementation FLAnimatedImageView (WebCache) + +- (NSURL *)sd_imageURL { + return objc_getAssociatedObject(self, &imageURLKey); +} + +- (void)sd_setAnimatedImageWithURL:(NSURL *)url { + [self sd_setAnimatedImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil]; +} + +- (void)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder { + [self sd_setAnimatedImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil]; +} + +- (void)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setAnimatedImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil]; +} + +- (void)sd_setAnimatedImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock { + [self sd_setAnimatedImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock]; +} + +- (void)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock { + [self sd_setAnimatedImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock]; +} + +- (void)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock { + [self sd_setAnimatedImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock]; +} + +- (void)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock { + [self sd_cancelCurrentAnimatedImageLoad]; + objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + + if (!(options & SDWebImageDelayPlaceholder)) { + dispatch_main_async_safe(^{ + self.image = placeholder; + }); + } + + if (url) { + // check if activityView is enabled or not + if ([self showActivityIndicatorView]) { + [self addActivityIndicator]; + } + + __weak __typeof(self)wself = self; + id operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + if (!wself) return; + dispatch_main_sync_safe(^{ + [wself removeActivityIndicator]; + + if (!wself) return; + if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock) { + completedBlock(image, error, cacheType, url); + return; + } else if (image) { + NSString *imageContentType = [NSData sd_contentTypeForImageData:data]; + if ([imageContentType isEqualToString:@"image/gif"]) { + wself.animatedImage = [FLAnimatedImage animatedImageWithGIFData:data]; + wself.image = nil; + } else { + wself.image = image; + wself.animatedImage = nil; + } + [wself setNeedsLayout]; + } else { + if ((options & SDWebImageDelayPlaceholder)) { + wself.image = placeholder; + [wself setNeedsLayout]; + } + } + if (completedBlock && finished) { + completedBlock(image, error, cacheType, url); + } + }); + }]; + [self sd_setImageLoadOperation:operation forKey:@"UIImageViewAnimatedImageLoad"]; + } else { + dispatch_main_async_safe(^{ + [self removeActivityIndicator]; + + if (completedBlock) { + NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; + completedBlock(nil, error, SDImageCacheTypeNone, url); + } + }); + } +} + +- (void)sd_cancelCurrentAnimatedImageLoad { + [self sd_cancelImageLoadOperationWithKey:@"UIImageViewAnimatedImageLoad"]; +} + + +@end From f6cd50bb653e5964ca7badd10669bc27bb44f369 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 10:05:40 +0300 Subject: [PATCH 12/19] Converted our example xibs to the new Xcode format --- .../en.lproj/DetailViewController.xib | 192 +++--------------- .../en.lproj/MasterViewController.xib | 164 +++------------ 2 files changed, 53 insertions(+), 303 deletions(-) diff --git a/Examples/SDWebImage Demo/en.lproj/DetailViewController.xib b/Examples/SDWebImage Demo/en.lproj/DetailViewController.xib index ccce9b18..c3e3aad5 100644 --- a/Examples/SDWebImage Demo/en.lproj/DetailViewController.xib +++ b/Examples/SDWebImage Demo/en.lproj/DetailViewController.xib @@ -1,164 +1,28 @@ - - - - 1296 - 11D50b - 2182 - 1138.32 - 568.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1181 - - - IBProxyObject - IBUIView - IBUIImageView - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - - - - 274 - {320, 460} - - - _NS:9 - 1 - NO - IBCocoaTouchFramework - - - {{0, 20}, {320, 460}} - - - - 3 - MQA - - 2 - - - - IBCocoaTouchFramework - - - - - - - view - - - - 3 - - - - imageView - - - - 8 - - - - - - 0 - - - - - - 1 - - - - - - - - -1 - - - File's Owner - - - -2 - - - - - 7 - - - - - - - DetailViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 8 - - - - - DetailViewController - UIViewController - - imageView - UIImageView - - - imageView - - imageView - UIImageView - - - - IBProjectSource - ./Classes/DetailViewController.h - - - - - 0 - IBCocoaTouchFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - - YES - 3 - 1181 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/SDWebImage Demo/en.lproj/MasterViewController.xib b/Examples/SDWebImage Demo/en.lproj/MasterViewController.xib index 729e0153..13abc1c6 100644 --- a/Examples/SDWebImage Demo/en.lproj/MasterViewController.xib +++ b/Examples/SDWebImage Demo/en.lproj/MasterViewController.xib @@ -1,139 +1,25 @@ - - - - 1280 - 11C25 - 1919 - 1138.11 - 566.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 916 - - - IBProxyObject - IBUITableView - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - {{0, 20}, {320, 460}} - - - - 3 - MQA - - YES - - IBCocoaTouchFramework - YES - 1 - 0 - YES - 44 - 22 - 22 - - - - - - - view - - - - 3 - - - - dataSource - - - - 4 - - - - delegate - - - - 5 - - - - - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 2 - - - - - - - MasterViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 5 - - - - - MasterViewController - UITableViewController - - IBProjectSource - ./Classes/MasterViewController.h - - - - - 0 - IBCocoaTouchFramework - YES - 3 - 916 - - + + + + + + + + + + + + + + + + + + + + + + + + + From 4df3934954cf34945f41d2f8fe8c779bafdc86db Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 10:06:19 +0300 Subject: [PATCH 13/19] Added the FLAnimatedImageView category to the project and made the FLAnimatedImage headers public --- SDWebImage.xcodeproj/project.pbxproj | 36 +++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/SDWebImage.xcodeproj/project.pbxproj b/SDWebImage.xcodeproj/project.pbxproj index b2c77227..2198a5f0 100644 --- a/SDWebImage.xcodeproj/project.pbxproj +++ b/SDWebImage.xcodeproj/project.pbxproj @@ -271,18 +271,24 @@ 438096731CDFC08F00DC626B /* MKAnnotationView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 535699B515113E7300A4C397 /* MKAnnotationView+WebCache.m */; }; 438096741CDFC09C00DC626B /* UIImage+WebP.h in Headers */ = {isa = PBXBuildFile; fileRef = 53EDFB911762547C00698166 /* UIImage+WebP.h */; settings = {ATTRIBUTES = (Public, ); }; }; 438096751CDFC0A100DC626B /* UIImage+WebP.m in Sources */ = {isa = PBXBuildFile; fileRef = 53EDFB921762547C00698166 /* UIImage+WebP.m */; }; - 43CE75761CFE9427006C64D0 /* FLAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE75491CFE9427006C64D0 /* FLAnimatedImage.h */; }; - 43CE75771CFE9427006C64D0 /* FLAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE75491CFE9427006C64D0 /* FLAnimatedImage.h */; }; - 43CE75781CFE9427006C64D0 /* FLAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE75491CFE9427006C64D0 /* FLAnimatedImage.h */; }; + 43CE75761CFE9427006C64D0 /* FLAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE75491CFE9427006C64D0 /* FLAnimatedImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 43CE75771CFE9427006C64D0 /* FLAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE75491CFE9427006C64D0 /* FLAnimatedImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 43CE75781CFE9427006C64D0 /* FLAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE75491CFE9427006C64D0 /* FLAnimatedImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; 43CE75791CFE9427006C64D0 /* FLAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 43CE754A1CFE9427006C64D0 /* FLAnimatedImage.m */; }; 43CE757A1CFE9427006C64D0 /* FLAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 43CE754A1CFE9427006C64D0 /* FLAnimatedImage.m */; }; 43CE757B1CFE9427006C64D0 /* FLAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 43CE754A1CFE9427006C64D0 /* FLAnimatedImage.m */; }; - 43CE757C1CFE9427006C64D0 /* FLAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE754B1CFE9427006C64D0 /* FLAnimatedImageView.h */; }; - 43CE757D1CFE9427006C64D0 /* FLAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE754B1CFE9427006C64D0 /* FLAnimatedImageView.h */; }; - 43CE757E1CFE9427006C64D0 /* FLAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE754B1CFE9427006C64D0 /* FLAnimatedImageView.h */; }; + 43CE757C1CFE9427006C64D0 /* FLAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE754B1CFE9427006C64D0 /* FLAnimatedImageView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 43CE757D1CFE9427006C64D0 /* FLAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE754B1CFE9427006C64D0 /* FLAnimatedImageView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 43CE757E1CFE9427006C64D0 /* FLAnimatedImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE754B1CFE9427006C64D0 /* FLAnimatedImageView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 43CE757F1CFE9427006C64D0 /* FLAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 43CE754C1CFE9427006C64D0 /* FLAnimatedImageView.m */; }; 43CE75801CFE9427006C64D0 /* FLAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 43CE754C1CFE9427006C64D0 /* FLAnimatedImageView.m */; }; 43CE75811CFE9427006C64D0 /* FLAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 43CE754C1CFE9427006C64D0 /* FLAnimatedImageView.m */; }; + 43CE75D01CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE75CE1CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 43CE75D11CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE75CE1CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 43CE75D21CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CE75CE1CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 43CE75D31CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 43CE75CF1CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.m */; }; + 43CE75D41CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 43CE75CF1CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.m */; }; + 43CE75D51CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 43CE75CF1CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.m */; }; 4A2CAE041AB4BB5400B6BC39 /* SDWebImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A2CAE031AB4BB5400B6BC39 /* SDWebImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4A2CAE181AB4BB6400B6BC39 /* SDWebImageCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 53922D88148C56230056699D /* SDWebImageCompat.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4A2CAE191AB4BB6400B6BC39 /* SDWebImageCompat.m in Sources */ = {isa = PBXBuildFile; fileRef = 5340674F167780C40042B59E /* SDWebImageCompat.m */; }; @@ -357,6 +363,8 @@ 43CE754A1CFE9427006C64D0 /* FLAnimatedImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLAnimatedImage.m; sourceTree = ""; }; 43CE754B1CFE9427006C64D0 /* FLAnimatedImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLAnimatedImageView.h; sourceTree = ""; }; 43CE754C1CFE9427006C64D0 /* FLAnimatedImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLAnimatedImageView.m; sourceTree = ""; }; + 43CE75CE1CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLAnimatedImageView+WebCache.h"; sourceTree = ""; }; + 43CE75CF1CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "FLAnimatedImageView+WebCache.m"; sourceTree = ""; }; 4A2CADFF1AB4BB5300B6BC39 /* SDWebImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4A2CAE021AB4BB5400B6BC39 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4A2CAE031AB4BB5400B6BC39 /* SDWebImage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImage.h; sourceTree = ""; }; @@ -523,6 +531,15 @@ path = FLAnimatedImage; sourceTree = ""; }; + 43CE75CD1CFE98B3006C64D0 /* FLAnimatedImage */ = { + isa = PBXGroup; + children = ( + 43CE75CE1CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.h */, + 43CE75CF1CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.m */, + ); + path = FLAnimatedImage; + sourceTree = ""; + }; 4A2CAE001AB4BB5300B6BC39 /* WebImage */ = { isa = PBXGroup; children = ( @@ -583,6 +600,7 @@ 53922DAA148C56470056699D /* Cache */, 53922DAC148C56DD0056699D /* Utils */, 53922DA9148C562D0056699D /* Categories */, + 43CE75CD1CFE98B3006C64D0 /* FLAnimatedImage */, ); path = SDWebImage; sourceTree = ""; @@ -795,6 +813,7 @@ 00733A6C1BC4880E00A5A117 /* UIButton+WebCache.h in Headers */, 431738DF1CDFC8A40008FEB9 /* vp8li.h in Headers */, 4317395B1CDFC8B70008FEB9 /* types.h in Headers */, + 43CE75D21CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.h in Headers */, 431739551CDFC8B70008FEB9 /* decode.h in Headers */, 00733A731BC4880E00A5A117 /* SDWebImage.h in Headers */, 00733A701BC4880E00A5A117 /* UIImageView+HighlightedWebCache.h in Headers */, @@ -849,6 +868,7 @@ 4317392F1CDFC8B20008FEB9 /* rescaler.h in Headers */, 4A2CAE181AB4BB6400B6BC39 /* SDWebImageCompat.h in Headers */, 4317391B1CDFC8B20008FEB9 /* bit_reader.h in Headers */, + 43CE75D11CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.h in Headers */, 4A2CAE331AB4BB7500B6BC39 /* UIImageView+HighlightedWebCache.h in Headers */, 431739521CDFC8B70008FEB9 /* mux.h in Headers */, 431738F11CDFC8AA0008FEB9 /* lossless.h in Headers */, @@ -910,6 +930,7 @@ 53761318155AD0D5005750A4 /* SDWebImageCompat.h in Headers */, 431738841CDFC2580008FEB9 /* vp8li.h in Headers */, 431738C31CDFC2660008FEB9 /* types.h in Headers */, + 43CE75D01CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.h in Headers */, 431738BD1CDFC2660008FEB9 /* decode.h in Headers */, 53761319155AD0D5005750A4 /* SDWebImageDecoder.h in Headers */, 5376131A155AD0D5005750A4 /* SDWebImageDownloader.h in Headers */, @@ -1081,6 +1102,7 @@ 431739391CDFC8B20008FEB9 /* color_cache.c in Sources */, 00733A5A1BC4880000A5A117 /* SDWebImagePrefetcher.m in Sources */, 431739031CDFC8AA0008FEB9 /* dec_mips32.c in Sources */, + 43CE75D51CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.m in Sources */, 4317390B1CDFC8AA0008FEB9 /* enc_sse2.c in Sources */, 00733A5B1BC4880000A5A117 /* NSData+ImageContentType.m in Sources */, 431739131CDFC8AA0008FEB9 /* upsampling_neon.c in Sources */, @@ -1154,6 +1176,7 @@ 4A2CAE2E1AB4BB7500B6BC39 /* UIImage+GIF.m in Sources */, 4A2CAE321AB4BB7500B6BC39 /* UIImage+WebP.m in Sources */, 431738EC1CDFC8AA0008FEB9 /* enc_avx2.c in Sources */, + 43CE75D41CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.m in Sources */, 4317392E1CDFC8B20008FEB9 /* rescaler.c in Sources */, 431738E91CDFC8AA0008FEB9 /* dec_sse2.c in Sources */, 431738F71CDFC8AA0008FEB9 /* upsampling_neon.c in Sources */, @@ -1224,6 +1247,7 @@ 53761309155AD0D5005750A4 /* SDImageCache.m in Sources */, 5376130A155AD0D5005750A4 /* SDWebImageDecoder.m in Sources */, 431738911CDFC25E0008FEB9 /* enc_avx2.c in Sources */, + 43CE75D31CFE98E0006C64D0 /* FLAnimatedImageView+WebCache.m in Sources */, 431738B71CDFC2630008FEB9 /* rescaler.c in Sources */, 4317388E1CDFC25E0008FEB9 /* dec_sse2.c in Sources */, 4317389C1CDFC25E0008FEB9 /* upsampling_neon.c in Sources */, From 8a488d377b9a92edfa655ba3ac3d1c32f8c247a6 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 10:06:37 +0300 Subject: [PATCH 14/19] Updated the example project so it supports the animated images as well. --- .../SDWebImage Demo/DetailViewController.h | 2 - .../SDWebImage Demo/DetailViewController.m | 33 ++++++----- .../SDWebImage Demo/MasterViewController.m | 57 +++++++++++++++---- 3 files changed, 65 insertions(+), 27 deletions(-) diff --git a/Examples/SDWebImage Demo/DetailViewController.h b/Examples/SDWebImage Demo/DetailViewController.h index f4c6b76f..1272c090 100644 --- a/Examples/SDWebImage Demo/DetailViewController.h +++ b/Examples/SDWebImage Demo/DetailViewController.h @@ -12,6 +12,4 @@ @property (strong, nonatomic) NSURL *imageURL; -@property (strong, nonatomic) IBOutlet UIImageView *imageView; - @end diff --git a/Examples/SDWebImage Demo/DetailViewController.m b/Examples/SDWebImage Demo/DetailViewController.m index d7acf6a8..ef483bde 100644 --- a/Examples/SDWebImage Demo/DetailViewController.m +++ b/Examples/SDWebImage Demo/DetailViewController.m @@ -8,9 +8,14 @@ #import "DetailViewController.h" #import +#import @interface DetailViewController () + +@property (strong, nonatomic) IBOutlet FLAnimatedImageView *imageView; + - (void)configureView; + @end @implementation DetailViewController @@ -34,20 +39,20 @@ if (self.imageURL) { __block UIActivityIndicatorView *activityIndicator; __weak UIImageView *weakImageView = self.imageView; - [self.imageView sd_setImageWithURL:self.imageURL - placeholderImage:nil - options:SDWebImageProgressiveDownload - progress:^(NSInteger receivedSize, NSInteger expectedSize) { - if (!activityIndicator) { - [weakImageView addSubview:activityIndicator = [UIActivityIndicatorView.alloc initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]]; - activityIndicator.center = weakImageView.center; - [activityIndicator startAnimating]; - } - } - completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { - [activityIndicator removeFromSuperview]; - activityIndicator = nil; - }]; + [self.imageView sd_setAnimatedImageWithURL:self.imageURL + placeholderImage:nil + options:SDWebImageProgressiveDownload + progress:^(NSInteger receivedSize, NSInteger expectedSize) { + if (!activityIndicator) { + [weakImageView addSubview:activityIndicator = [UIActivityIndicatorView.alloc initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]]; + activityIndicator.center = weakImageView.center; + [activityIndicator startAnimating]; + } + } + completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + [activityIndicator removeFromSuperview]; + activityIndicator = nil; + }]; } } diff --git a/Examples/SDWebImage Demo/MasterViewController.m b/Examples/SDWebImage Demo/MasterViewController.m index 57711c44..1addc8e0 100644 --- a/Examples/SDWebImage Demo/MasterViewController.m +++ b/Examples/SDWebImage Demo/MasterViewController.m @@ -9,6 +9,36 @@ #import "MasterViewController.h" #import #import "DetailViewController.h" +#import +#import + + +@interface MyCustomTableViewCell : UITableViewCell + +@property (nonatomic, strong) UILabel *customTextLabel; +@property (nonatomic, strong) FLAnimatedImageView *customImageView; + +@end + + +@implementation MyCustomTableViewCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { + _customImageView = [[FLAnimatedImageView alloc] initWithFrame:CGRectMake(20.0, 2.0, 60.0, 40.0)]; + [self.contentView addSubview:_customImageView]; + _customTextLabel = [[UILabel alloc] initWithFrame:CGRectMake(100.0, 12.0, 200, 20.0)]; + [self.contentView addSubview:_customTextLabel]; + + _customImageView.clipsToBounds = YES; + _customImageView.contentMode = UIViewContentModeScaleAspectFill; + } + return self; +} + +@end + + @interface MasterViewController () { NSMutableArray *_objects; @@ -38,6 +68,7 @@ _objects = [NSMutableArray arrayWithObjects: @"http://www.httpwatch.com/httpgallery/authentication/authenticatedimage/default.aspx?0.35786508303135633", // requires HTTP auth, used to demo the NTLM auth @"http://assets.sbnation.com/assets/2512203/dogflops.gif", + @"https://raw.githubusercontent.com/liyong03/YLGIFImage/master/YLGIFImageDemo/YLGIFImageDemo/joy.gif", @"http://www.ioncannon.net/wp-content/uploads/2011/06/test2.webp", @"http://www.ioncannon.net/wp-content/uploads/2011/06/test9.webp", nil]; @@ -79,19 +110,23 @@ { static NSString *CellIdentifier = @"Cell"; - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; - if (cell == nil) - { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; + static UIImage *placeholderImage = nil; + if (!placeholderImage) { + placeholderImage = [UIImage imageNamed:@"placeholder"]; + } + + MyCustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) { + cell = [[MyCustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } - [cell.imageView setShowActivityIndicatorView:YES]; - [cell.imageView setIndicatorStyle:UIActivityIndicatorViewStyleGray]; - - cell.textLabel.text = [NSString stringWithFormat:@"Image #%ld", (long)indexPath.row]; - cell.imageView.contentMode = UIViewContentModeScaleAspectFill; - [cell.imageView sd_setImageWithURL:[NSURL URLWithString:_objects[indexPath.row]] - placeholderImage:[UIImage imageNamed:@"placeholder"] options:indexPath.row == 0 ? SDWebImageRefreshCached : 0]; + [cell.customImageView setShowActivityIndicatorView:YES]; + [cell.customImageView setIndicatorStyle:UIActivityIndicatorViewStyleGray]; + + cell.customTextLabel.text = [NSString stringWithFormat:@"Image #%ld", (long)indexPath.row]; + [cell.customImageView sd_setAnimatedImageWithURL:[NSURL URLWithString:_objects[indexPath.row]] + placeholderImage:placeholderImage + options:indexPath.row == 0 ? SDWebImageRefreshCached : 0]; return cell; } From d75bc2765d3dec1b54f4640bb89ed17cab1e6a9d Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 10:10:46 +0300 Subject: [PATCH 15/19] Updated the podspec so the GIF+FLAnimatedImage is a separate subspec --- SDWebImage.podspec | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/SDWebImage.podspec b/SDWebImage.podspec index 646126f6..0aab1a63 100644 --- a/SDWebImage.podspec +++ b/SDWebImage.podspec @@ -35,6 +35,16 @@ Pod::Spec.new do |s| mk.dependency 'SDWebImage/Core' end + s.subspec 'GIF' do |gif| + gif.ios.deployment_target = '6.0' + gif.source_files = 'SDWebImage/FLAnimatedImage/*.{h,m}' + gif.dependency 'SDWebImage/Core' + gif.dependency 'FLAnimatedImage', '~> 1.0' + gif.xcconfig = { + 'USER_HEADER_SEARCH_PATHS' => '$(inherited) $(SRCROOT)/FLAnimatedImage/FLAnimatedImage' + } + end + s.subspec 'WebP' do |webp| webp.source_files = 'SDWebImage/UIImage+WebP.{h,m}' webp.xcconfig = { From 44cb993ee9af59aad1b282c5fa414aac511cd265 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 10:11:46 +0300 Subject: [PATCH 16/19] Successfull attempt to override the UIImageView(WebCache) methods in the FLAnimatedImageView(WebCache) category. This should make the integration easier. Not sure if it will always work --- .../SDWebImage Demo/DetailViewController.m | 28 +++++++-------- .../SDWebImage Demo/MasterViewController.m | 6 ++-- .../FLAnimatedImageView+WebCache.h | 16 ++++----- .../FLAnimatedImageView+WebCache.m | 34 +++++++++---------- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/Examples/SDWebImage Demo/DetailViewController.m b/Examples/SDWebImage Demo/DetailViewController.m index ef483bde..da57ed71 100644 --- a/Examples/SDWebImage Demo/DetailViewController.m +++ b/Examples/SDWebImage Demo/DetailViewController.m @@ -39,20 +39,20 @@ if (self.imageURL) { __block UIActivityIndicatorView *activityIndicator; __weak UIImageView *weakImageView = self.imageView; - [self.imageView sd_setAnimatedImageWithURL:self.imageURL - placeholderImage:nil - options:SDWebImageProgressiveDownload - progress:^(NSInteger receivedSize, NSInteger expectedSize) { - if (!activityIndicator) { - [weakImageView addSubview:activityIndicator = [UIActivityIndicatorView.alloc initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]]; - activityIndicator.center = weakImageView.center; - [activityIndicator startAnimating]; - } - } - completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { - [activityIndicator removeFromSuperview]; - activityIndicator = nil; - }]; + [self.imageView sd_setImageWithURL:self.imageURL + placeholderImage:nil + options:SDWebImageProgressiveDownload + progress:^(NSInteger receivedSize, NSInteger expectedSize) { + if (!activityIndicator) { + [weakImageView addSubview:activityIndicator = [UIActivityIndicatorView.alloc initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]]; + activityIndicator.center = weakImageView.center; + [activityIndicator startAnimating]; + } + } + completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + [activityIndicator removeFromSuperview]; + activityIndicator = nil; + }]; } } diff --git a/Examples/SDWebImage Demo/MasterViewController.m b/Examples/SDWebImage Demo/MasterViewController.m index 1addc8e0..4e580ccc 100644 --- a/Examples/SDWebImage Demo/MasterViewController.m +++ b/Examples/SDWebImage Demo/MasterViewController.m @@ -124,9 +124,9 @@ [cell.customImageView setIndicatorStyle:UIActivityIndicatorViewStyleGray]; cell.customTextLabel.text = [NSString stringWithFormat:@"Image #%ld", (long)indexPath.row]; - [cell.customImageView sd_setAnimatedImageWithURL:[NSURL URLWithString:_objects[indexPath.row]] - placeholderImage:placeholderImage - options:indexPath.row == 0 ? SDWebImageRefreshCached : 0]; + [cell.customImageView sd_setImageWithURL:[NSURL URLWithString:_objects[indexPath.row]] + placeholderImage:placeholderImage + options:indexPath.row == 0 ? SDWebImageRefreshCached : 0]; return cell; } diff --git a/SDWebImage/FLAnimatedImage/FLAnimatedImageView+WebCache.h b/SDWebImage/FLAnimatedImage/FLAnimatedImageView+WebCache.h index dfccad62..b0b31f08 100644 --- a/SDWebImage/FLAnimatedImage/FLAnimatedImageView+WebCache.h +++ b/SDWebImage/FLAnimatedImage/FLAnimatedImageView+WebCache.h @@ -36,7 +36,7 @@ * * @param url The url for the image. */ -- (void)sd_setAnimatedImageWithURL:(NSURL *)url; +- (void)sd_setImageWithURL:(NSURL *)url; /** * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images @@ -46,7 +46,7 @@ * @param url The url for the image. * @param placeholder The image to be set initially, until the image request finishes. */ -- (void)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; /** * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images @@ -57,7 +57,7 @@ * @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)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; /** * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images @@ -70,7 +70,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setAnimatedImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock; /** * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images @@ -85,7 +85,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock; /** * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images @@ -101,7 +101,7 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock; /** * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images @@ -118,11 +118,11 @@ * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ -- (void)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock; /** * Cancel the image load */ -- (void)sd_cancelCurrentAnimatedImageLoad; +- (void)sd_cancelCurrentImageLoad; @end diff --git a/SDWebImage/FLAnimatedImage/FLAnimatedImageView+WebCache.m b/SDWebImage/FLAnimatedImage/FLAnimatedImageView+WebCache.m index 3b90f053..9c436e5f 100644 --- a/SDWebImage/FLAnimatedImage/FLAnimatedImageView+WebCache.m +++ b/SDWebImage/FLAnimatedImage/FLAnimatedImageView+WebCache.m @@ -23,32 +23,32 @@ static char imageURLKey; return objc_getAssociatedObject(self, &imageURLKey); } -- (void)sd_setAnimatedImageWithURL:(NSURL *)url { - [self sd_setAnimatedImageWithURL: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)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder { - [self sd_setAnimatedImageWithURL: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)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { - [self sd_setAnimatedImageWithURL: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)sd_setAnimatedImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock { - [self sd_setAnimatedImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock]; +- (void)sd_setImageWithURL:(NSURL *)url completed:(SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock]; } -- (void)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock { - [self sd_setAnimatedImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock]; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock]; } -- (void)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock { - [self sd_setAnimatedImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock]; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDExternalCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock]; } -- (void)sd_setAnimatedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock { - [self sd_cancelCurrentAnimatedImageLoad]; +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDExternalCompletionBlock)completedBlock { + [self sd_cancelCurrentImageLoad]; objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); if (!(options & SDWebImageDelayPlaceholder)) { @@ -94,7 +94,7 @@ static char imageURLKey; } }); }]; - [self sd_setImageLoadOperation:operation forKey:@"UIImageViewAnimatedImageLoad"]; + [self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"]; } else { dispatch_main_async_safe(^{ [self removeActivityIndicator]; @@ -107,8 +107,8 @@ static char imageURLKey; } } -- (void)sd_cancelCurrentAnimatedImageLoad { - [self sd_cancelImageLoadOperationWithKey:@"UIImageViewAnimatedImageLoad"]; +- (void)sd_cancelCurrentImageLoad { + [self sd_cancelImageLoadOperationWithKey:@"UIImageViewImageLoad"]; } From d1f76940044edf53267d3e84fafd5bb4d5b38463 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 10:17:59 +0300 Subject: [PATCH 17/19] Trying to fix the build, seems like Travis cannot work with ssh urls --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index c3be261d..d8c3ae83 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,4 +3,4 @@ url = https://github.com/webmproject/libwebp [submodule "Vendors/FLAnimatedImage"] path = Vendors/FLAnimatedImage - url = git@github.com:Flipboard/FLAnimatedImage.git + url = https://github.com/Flipboard/FLAnimatedImage From b059b04fd21f666ad4137d6a1de0eac1c94a6fc9 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 10:32:40 +0300 Subject: [PATCH 18/19] Updated the tests --- Tests/Tests/SDImageCacheTests.m | 2 +- Tests/Tests/SDWebImageManagerTests.m | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Tests/Tests/SDImageCacheTests.m b/Tests/Tests/SDImageCacheTests.m index 231ea839..4480aafb 100644 --- a/Tests/Tests/SDImageCacheTests.m +++ b/Tests/Tests/SDImageCacheTests.m @@ -100,7 +100,7 @@ NSString *kImageTestKey = @"TestImageKey.jpg"; //- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDWebImageQueryCompletedBlock)doneBlock; UIImage *imageForTesting = [self imageForTesting]; [self.sharedImageCache storeImage:imageForTesting forKey:kImageTestKey]; - NSOperation *operation = [self.sharedImageCache queryDiskCacheForKey:kImageTestKey done:^(UIImage *image, SDImageCacheType cacheType) { + NSOperation *operation = [self.sharedImageCache queryDiskCacheForKey:kImageTestKey done:^(UIImage *image, NSData *data, SDImageCacheType cacheType) { expect(image).to.equal(imageForTesting); }]; expect(operation).toNot.beNil; diff --git a/Tests/Tests/SDWebImageManagerTests.m b/Tests/Tests/SDWebImageManagerTests.m index cf26720b..dc34d3a9 100644 --- a/Tests/Tests/SDWebImageManagerTests.m +++ b/Tests/Tests/SDWebImageManagerTests.m @@ -40,7 +40,10 @@ static int64_t kAsyncTestTimeout = 5; NSURL *originalImageURL = [NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage000.jpg"]; - [[SDWebImageManager sharedManager] loadImageWithURL:originalImageURL options:SDWebImageRefreshCached progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + [[SDWebImageManager sharedManager] loadImageWithURL:originalImageURL + options:SDWebImageRefreshCached + progress:nil + completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { expect(image).toNot.beNil(); expect(error).to.beNil(); expect(originalImageURL).to.equal(imageURL); @@ -57,7 +60,10 @@ static int64_t kAsyncTestTimeout = 5; NSURL *originalImageURL = [NSURL URLWithString:@"http://static2.dmcdn.net/static/video/656/177/44771656:jpeg_preview_small.png"]; - [[SDWebImageManager sharedManager] loadImageWithURL:originalImageURL options:SDWebImageRefreshCached progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + [[SDWebImageManager sharedManager] loadImageWithURL:originalImageURL + options:SDWebImageRefreshCached + progress:nil + completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { expect(image).to.beNil(); expect(error).toNot.beNil(); expect(originalImageURL).to.equal(imageURL); From 7761afca9279e6cbbd0f82b98b2db0b8d2d78af3 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 11:58:39 +0300 Subject: [PATCH 19/19] Trying to fix the random build failures (probably timeout due to this image url) --- Tests/Tests/SDWebImageDownloaderTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Tests/SDWebImageDownloaderTests.m b/Tests/Tests/SDWebImageDownloaderTests.m index 233711fa..7fa5c5c8 100644 --- a/Tests/Tests/SDWebImageDownloaderTests.m +++ b/Tests/Tests/SDWebImageDownloaderTests.m @@ -35,7 +35,7 @@ - (void)testThatDownloadingSameURLTwiceAndCancellingFirstWorks { XCTestExpectation *expectation = [self expectationWithDescription:@"Correct image downloads"]; - NSURL *imageURL = [NSURL URLWithString:@"http://static2.dmcdn.net/static/video/656/177/44771656:jpeg_preview_small.jpg?20120509154705"]; + NSURL *imageURL = [NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage000.jpg"]; id token1 = [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:imageURL options:0