Selaa lähdekoodia

Add SDWebImageOptionsProcessor, which can have a global control for both WebCache options and context option for image loading

DreamPiggy 6 vuotta sitten
vanhempi
sitoutus
26d1a95cca

+ 12 - 0
SDWebImage.xcodeproj/project.pbxproj

@@ -37,6 +37,10 @@
 		321E60C61F38E91700405457 /* UIImage+ForceDecode.m in Sources */ = {isa = PBXBuildFile; fileRef = 321E60BD1F38E91700405457 /* UIImage+ForceDecode.m */; };
 		3237F9E820161AE000A88143 /* NSImage+Compatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 4397D2F51D0DE2DF00BB2784 /* NSImage+Compatibility.m */; };
 		3237F9EB20161AE000A88143 /* NSImage+Compatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 4397D2F51D0DE2DF00BB2784 /* NSImage+Compatibility.m */; };
+		3244062B2296C5F400A36084 /* SDWebImageOptionsProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 324406292296C5F400A36084 /* SDWebImageOptionsProcessor.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		3244062C2296C5F400A36084 /* SDWebImageOptionsProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 324406292296C5F400A36084 /* SDWebImageOptionsProcessor.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		3244062D2296C5F400A36084 /* SDWebImageOptionsProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = 3244062A2296C5F400A36084 /* SDWebImageOptionsProcessor.m */; };
+		3244062E2296C5F400A36084 /* SDWebImageOptionsProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = 3244062A2296C5F400A36084 /* SDWebImageOptionsProcessor.m */; };
 		3248475D201775F600AF9E5A /* SDAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 32484757201775F600AF9E5A /* SDAnimatedImageView.m */; };
 		3248475F201775F600AF9E5A /* SDAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 32484757201775F600AF9E5A /* SDAnimatedImageView.m */; };
 		32484763201775F600AF9E5A /* SDAnimatedImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 32484758201775F600AF9E5A /* SDAnimatedImageView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -275,6 +279,8 @@
 		321E60A11F38E8F600405457 /* SDImageGIFCoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDImageGIFCoder.m; sourceTree = "<group>"; };
 		321E60BC1F38E91700405457 /* UIImage+ForceDecode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+ForceDecode.h"; sourceTree = "<group>"; };
 		321E60BD1F38E91700405457 /* UIImage+ForceDecode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+ForceDecode.m"; sourceTree = "<group>"; };
+		324406292296C5F400A36084 /* SDWebImageOptionsProcessor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImageOptionsProcessor.h; sourceTree = "<group>"; };
+		3244062A2296C5F400A36084 /* SDWebImageOptionsProcessor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageOptionsProcessor.m; sourceTree = "<group>"; };
 		32484757201775F600AF9E5A /* SDAnimatedImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDAnimatedImageView.m; sourceTree = "<group>"; };
 		32484758201775F600AF9E5A /* SDAnimatedImageView+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SDAnimatedImageView+WebCache.h"; sourceTree = "<group>"; };
 		32484759201775F600AF9E5A /* SDAnimatedImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDAnimatedImageView.h; sourceTree = "<group>"; };
@@ -465,6 +471,8 @@
 				328BB69B2081FED200760D6C /* SDWebImageCacheKeyFilter.m */,
 				328BB6A82081FEE500760D6C /* SDWebImageCacheSerializer.h */,
 				328BB6A92081FEE500760D6C /* SDWebImageCacheSerializer.m */,
+				324406292296C5F400A36084 /* SDWebImageOptionsProcessor.h */,
+				3244062A2296C5F400A36084 /* SDWebImageOptionsProcessor.m */,
 			);
 			name = Manager;
 			sourceTree = "<group>";
@@ -728,6 +736,7 @@
 				329F1237223FAA3B00B309FD /* SDmetamacros.h in Headers */,
 				324DF4B6200A14DC008A84CC /* SDWebImageDefine.h in Headers */,
 				807A122A1F89636300EC2A9B /* SDImageCodersManager.h in Headers */,
+				3244062C2296C5F400A36084 /* SDWebImageOptionsProcessor.h in Headers */,
 				4A2CAE211AB4BB7000B6BC39 /* SDWebImageManager.h in Headers */,
 				4A2CAE1F1AB4BB6C00B6BC39 /* SDImageCache.h in Headers */,
 				4A2CAE351AB4BB7500B6BC39 /* UIImageView+WebCache.h in Headers */,
@@ -795,6 +804,7 @@
 				329F1236223FAA3B00B309FD /* SDmetamacros.h in Headers */,
 				32484775201775F600AF9E5A /* SDAnimatedImage.h in Headers */,
 				321E60941F38E8ED00405457 /* SDImageIOCoder.h in Headers */,
+				3244062B2296C5F400A36084 /* SDWebImageOptionsProcessor.h in Headers */,
 				329A18591FFF5DFD008C9A2F /* UIImage+Metadata.h in Headers */,
 				32D122302080B2EB003685A3 /* SDImageCachesManager.h in Headers */,
 				5376131A155AD0D5005750A4 /* SDWebImageDownloader.h in Headers */,
@@ -963,6 +973,7 @@
 				3290FA0C1FA478AF0047D20C /* SDImageFrame.m in Sources */,
 				325C46232233A02E004CAE11 /* UIColor+HexString.m in Sources */,
 				321E60C61F38E91700405457 /* UIImage+ForceDecode.m in Sources */,
+				3244062E2296C5F400A36084 /* SDWebImageOptionsProcessor.m in Sources */,
 				328BB6A42081FED200760D6C /* SDWebImageCacheKeyFilter.m in Sources */,
 				4A2CAE2E1AB4BB7500B6BC39 /* UIImage+GIF.m in Sources */,
 				80B6DF822142B44400BCB334 /* NSButton+WebCache.m in Sources */,
@@ -1025,6 +1036,7 @@
 				3290FA0A1FA478AF0047D20C /* SDImageFrame.m in Sources */,
 				325C46222233A02E004CAE11 /* UIColor+HexString.m in Sources */,
 				321E60C41F38E91700405457 /* UIImage+ForceDecode.m in Sources */,
+				3244062D2296C5F400A36084 /* SDWebImageOptionsProcessor.m in Sources */,
 				328BB6A22081FED200760D6C /* SDWebImageCacheKeyFilter.m in Sources */,
 				53761309155AD0D5005750A4 /* SDImageCache.m in Sources */,
 				80B6DF832142B44500BCB334 /* NSButton+WebCache.m in Sources */,

+ 27 - 0
SDWebImage/SDWebImageManager.h

@@ -13,6 +13,7 @@
 #import "SDImageTransformer.h"
 #import "SDWebImageCacheKeyFilter.h"
 #import "SDWebImageCacheSerializer.h"
+#import "SDWebImageOptionsProcessor.h"
 
 typedef void(^SDExternalCompletionBlock)(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL);
 
@@ -153,6 +154,32 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
  */
 @property (nonatomic, strong, nullable) id<SDWebImageCacheSerializer> cacheSerializer;
 
+/**
+ The options processor is used, to have a global control for all the image request options and context option for current manager.
+ @note If you use `transformer`, `cacheKeyFilter` or `cacheSerializer` property of manager, the input context option already apply those properties before passed. This options processor is a better replacement for those property in common usage.
+ For example, you can control the global options, based on the URL or original context option like the below code.
+ 
+ @code
+ SDWebImageManager.sharedManager.optionsProcessor = [SDWebImageOptionsProcessor optionsProcessorWithBlock:^SDWebImageOptionsResult * _Nullable(NSURL * _Nullable url, SDWebImageOptions options, SDWebImageContext * _Nullable context) {
+     // Only do animation on `SDAnimatedImageView`
+     if (!context[SDWebImageContextAnimatedImageClass]) {
+        options |= SDWebImageDecodeFirstFrameOnly;
+     }
+     // Do not force decode for png url
+     if ([url.lastPathComponent isEqualToString:@"png"]) {
+        options |= SDWebImageAvoidDecodeImage;
+     }
+     // Always use screen scale factor
+     SDWebImageMutableContext *mutableContext = [NSDictionary dictionaryWithDictionary:context];
+     mutableContext[SDWebImageContextImageScaleFactor] = @(UIScreen.mainScreen.scale);
+     context = [mutableContext copy];
+ 
+     return [[SDWebImageOptionsResult alloc] initWithOptions:options context:context];
+ }];
+ @endcode
+ */
+@property (nonatomic, strong, nullable) id<SDWebImageOptionsProcessor> optionsProcessor;
+
 /**
  * Check one or more operations running
  */

+ 18 - 8
SDWebImage/SDWebImageManager.m

@@ -151,11 +151,11 @@ static id<SDImageLoader> _defaultImageLoader;
     [self.runningOperations addObject:operation];
     SD_UNLOCK(self.runningOperationsLock);
     
-    // Preprocess the context arg to provide the default value from manager
-    context = [self processedContextWithContext:context];
+    // Preprocess the options and context arg to decide the final the result for manager
+    SDWebImageOptionsResult *result = [self processedResultForURL:url options:options context:context];
     
     // Start the entry to load image from cache
-    [self callCacheProcessForOperation:operation url:url options:options context:context progress:progressBlock completed:completedBlock];
+    [self callCacheProcessForOperation:operation url:url options:result.options context:result.context progress:progressBlock completed:completedBlock];
 
     return operation;
 }
@@ -381,7 +381,8 @@ static id<SDImageLoader> _defaultImageLoader;
     return shouldBlockFailedURL;
 }
 
-- (SDWebImageContext *)processedContextWithContext:(SDWebImageContext *)context {
+- (SDWebImageOptionsResult *)processedResultForURL:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context {
+    SDWebImageOptionsResult *result;
     SDWebImageMutableContext *mutableContext = [SDWebImageMutableContext dictionary];
     
     // Image Transformer from manager
@@ -400,12 +401,21 @@ static id<SDImageLoader> _defaultImageLoader;
         [mutableContext setValue:cacheSerializer forKey:SDWebImageContextCacheSerializer];
     }
     
-    if (mutableContext.count == 0) {
-        return context;
-    } else {
+    if (mutableContext.count > 0) {
         [mutableContext addEntriesFromDictionary:context];
-        return [mutableContext copy];
+        context = [mutableContext copy];
+    }
+    
+    // Apply options processor
+    if (self.optionsProcessor) {
+        result = [self.optionsProcessor processedResultForURL:url options:options context:context];
     }
+    if (!result) {
+        // Use default options result
+        result = [[SDWebImageOptionsResult alloc] initWithOptions:options context:context];
+    }
+    
+    return result;
 }
 
 @end

+ 55 - 0
SDWebImage/SDWebImageOptionsProcessor.h

@@ -0,0 +1,55 @@
+/*
+ * This file is part of the SDWebImage package.
+ * (c) Olivier Poitrey <rs@dailymotion.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+#import <Foundation/Foundation.h>
+#import "SDWebImageCompat.h"
+#import "SDWebImageDefine.h"
+
+@class SDWebImageOptionsResult;
+
+typedef SDWebImageOptionsResult * _Nullable(^SDWebImageOptionsProcessorBlock)(NSURL * _Nullable url, SDWebImageOptions options, SDWebImageContext * _Nullable context);
+
+/**
+ The options result contains both options and context.
+ */
+@interface SDWebImageOptionsResult : NSObject
+
+@property (nonatomic, assign) SDWebImageOptions options;
+@property (nonatomic, copy, nullable) SDWebImageContext *context;
+
+- (nonnull instancetype)initWithOptions:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context;
+
+@end
+
+/**
+ This is the protocol for options processor.
+ Options processor can be used, to control the final result for individual image request's `SDWebImageOptions` and `SDWebImageContext`
+ Implements the protocol to have a global control for each indivadual image request's option.
+ */
+@protocol SDWebImageOptionsProcessor <NSObject>
+
+/**
+ Return the processed options result for specify image URL, with its options and context
+
+ @param url The URL to the image
+ @param options A mask to specify options to use for this request
+ @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
+ @return The processed result, contains both options and context
+ */
+- (nullable SDWebImageOptionsResult *)processedResultForURL:(nullable NSURL *)url
+                                                    options:(SDWebImageOptions)options
+                                                    context:(nullable SDWebImageContext *)context;
+
+@end
+
+@interface SDWebImageOptionsProcessor : NSObject<SDWebImageOptionsProcessor>
+
+- (nonnull instancetype)initWithBlock:(nonnull SDWebImageOptionsProcessorBlock)block;
++ (nonnull instancetype)optionsProcessorWithBlock:(nonnull SDWebImageOptionsProcessorBlock)block;
+
+@end

+ 52 - 0
SDWebImage/SDWebImageOptionsProcessor.m

@@ -0,0 +1,52 @@
+/*
+ * This file is part of the SDWebImage package.
+ * (c) Olivier Poitrey <rs@dailymotion.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+#import "SDWebImageOptionsProcessor.h"
+
+@implementation SDWebImageOptionsResult
+
+- (instancetype)initWithOptions:(SDWebImageOptions)options context:(SDWebImageContext *)context {
+    self = [super init];
+    if (self) {
+        self.options = options;
+        self.context = context;
+    }
+    return self;
+}
+
+@end
+
+@interface SDWebImageOptionsProcessor ()
+
+@property (nonatomic, copy, nonnull) SDWebImageOptionsProcessorBlock block;
+
+@end
+
+@implementation SDWebImageOptionsProcessor
+
+- (instancetype)initWithBlock:(SDWebImageOptionsProcessorBlock)block {
+    self = [super init];
+    if (self) {
+        self.block = block;
+    }
+    return self;
+}
+
++ (instancetype)optionsProcessorWithBlock:(SDWebImageOptionsProcessorBlock)block {
+    SDWebImageOptionsProcessor *optionsProcessor = [[SDWebImageOptionsProcessor alloc] initWithBlock:block];
+    return optionsProcessor;
+}
+
+- (SDWebImageOptionsResult *)processedResultForURL:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context {
+    if (!self.block) {
+        return nil;
+    }
+    return self.block(url, options, context);
+}
+
+@end

+ 1 - 0
WebImage/SDWebImage.h

@@ -66,6 +66,7 @@ FOUNDATION_EXPORT const unsigned char WebImageVersionString[];
 #import <SDWebImage/NSData+ImageContentType.h>
 #import <SDWebImage/SDWebImageDefine.h>
 #import <SDWebImage/SDWebImageError.h>
+#import <SDWebImage/SDWebImageOptionsProcessor.h>
 
 // Mac
 #if __has_include(<SDWebImage/NSImage+Compatibility.h>)