From 10aff8e1f0433dd4bb094a34c27db1f418888e51 Mon Sep 17 00:00:00 2001 From: Olivier Poitrey Date: Wed, 9 May 2012 11:04:09 +0200 Subject: [PATCH] Add cache key filter support to SDWebManager in order to allow custom cache key generation --- README.md | 34 ++++++++++++++++++++++++++++------ SDWebImageManager.h | 6 ++++++ SDWebImageManager.m | 28 ++++++++++++++++++++++++---- 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 8c3dca3f..8aa5206e 100644 --- a/README.md +++ b/README.md @@ -170,6 +170,28 @@ By default, the image will be stored in memory cache as well as on disk cache (a you want only the memory cache, use the alternative method storeImage:forKey:toDisk: with a negative third argument. +### Using cache key filter + +Sometime, you may not want to use the image URL as cache key because part of the URL is dynamic +(i.e.: for access control purpose). SDWebImageManager provides a way to set a cache key filter that +takes the NSURL as input, and output a cache key NSString. + +The following example sets a filter in the application delegate that will remove any query-string from +the URL before to use it as a cache key: + + - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions + { + [[SDWebImageManager sharedManager] setCacheKeyFilter:^(NSURL *url) + { + url = [[[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path] autorelease]; + return [url absoluteString]; + }]; + + // Your app init code... + return YES; + } + + Common Problems --------------- @@ -203,10 +225,10 @@ The following instructions are adapted from the excellent "Using Open Source Sta ### Add the SDWebImage project to your workspace -Make sure your project is in a workspace. If it's not, click File -> Save As Workspace first. +Make sure your project is in a workspace. If it's not, click File -> Save As Workspace first. Right-click on the project navigator and select "Add Files to "Your Project" and select SDWebImage.xcodeproj. -You may want to include the SDWebImage directory in your workspace repository before adding it to your project. +You may want to include the SDWebImage directory in your workspace repository before adding it to your project. ![Add SDWebImage](http://blog.carbonfive.com/wp-content/uploads/2011/04/adding_an_existing_project.png?w=300) @@ -214,7 +236,7 @@ You should end up with your project and SDWebimage project at the same level in ### Build libSDWebImage.a File -Set your build target to iOS Device, then click Build. Make sure the libSDWebImage.a file inside SDWebImage -> Products is not red. +Set your build target to iOS Device, then click Build. Make sure the libSDWebImage.a file inside SDWebImage -> Products is not red. ### Add build target dependency @@ -222,11 +244,11 @@ Select your project's build target and add the 'libSDWebImage.a' library to the ![Add target dependency](http://blog.carbonfive.com/wp-content/uploads/2011/04/linkable_libraries.png?w=214) -You may also need to add MapKit.framework here too as 'MKAnnotationView_WebCache.h' depends on it. +You may also need to add MapKit.framework here too as 'MKAnnotationView_WebCache.h' depends on it. ### Add headers -Open the "Build Settingsæ tab and locate the "User Header Search Paths" setting. Set this to +Open the "Build Settingsæ tab and locate the "User Header Search Paths" setting. Set this to "$(BUILT_PRODUCTS_DIR)/../../Headers" and check the "Recursive" check box. ![Header Search Paths](http://blog.carbonfive.com/wp-content/uploads/2011/04/header_search_path_value.png?w=300) @@ -234,7 +256,7 @@ Open the "Build Settingsæ tab and locate the "User Header Search Paths" setting Add the "-ObjC" flag to the "Other Linker Flags" build setting. ### Build Project -At this point your workspace should build without error. If you are having problem, post to the Issue and the community can help you solve it. +At this point your workspace should build without error. If you are having problem, post to the Issue and the community can help you solve it. ### Fixing indexing diff --git a/SDWebImageManager.h b/SDWebImageManager.h index e14f6325..6c4d8a73 100644 --- a/SDWebImageManager.h +++ b/SDWebImageManager.h @@ -28,6 +28,12 @@ typedef enum NSMutableArray *failedURLs; } +#if NS_BLOCKS_AVAILABLE +typedef NSString *(^CacheKeyFilter)(NSURL *url); +@property (strong) CacheKeyFilter cacheKeyFilter; +#endif + + + (id)sharedManager; - (UIImage *)imageWithURL:(NSURL *)url; - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate; diff --git a/SDWebImageManager.m b/SDWebImageManager.m index a66d4fe0..9d377713 100644 --- a/SDWebImageManager.m +++ b/SDWebImageManager.m @@ -20,6 +20,10 @@ static SDWebImageManager *instance; @implementation SDWebImageManager +#if NS_BLOCKS_AVAILABLE +@synthesize cacheKeyFilter; +#endif + - (id)init { if ((self = [super init])) @@ -56,12 +60,28 @@ static SDWebImageManager *instance; return instance; } +- (NSString *)cacheKeyForURL:(NSURL *)url +{ +#if NS_BLOCKS_AVAILABLE + if (self.cacheKeyFilter) + { + return self.cacheKeyFilter(url); + } + else + { + return [url absoluteString]; + } +#else + return [url absoluteString]; +#endif +} + /** * @deprecated */ - (UIImage *)imageWithURL:(NSURL *)url { - return [[SDImageCache sharedImageCache] imageFromKey:[url absoluteString]]; + return [[SDImageCache sharedImageCache] imageFromKey:[self cacheKeyForURL:url]]; } /** @@ -106,7 +126,7 @@ static SDWebImageManager *instance; [cacheDelegates addObject:delegate]; [cacheURLs addObject:url]; NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:delegate, @"delegate", url, @"url", [NSNumber numberWithInt:options], @"options", nil]; - [[SDImageCache sharedImageCache] queryDiskCacheForKey:[url absoluteString] delegate:self userInfo:info]; + [[SDImageCache sharedImageCache] queryDiskCacheForKey:[self cacheKeyForURL:url] delegate:self userInfo:info]; } #if NS_BLOCKS_AVAILABLE @@ -134,7 +154,7 @@ static SDWebImageManager *instance; NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:delegate, @"delegate", url, @"url", [NSNumber numberWithInt:options], @"options", successCopy, @"success", failureCopy, @"failure", nil]; SDWIRelease(successCopy); SDWIRelease(failureCopy); - [[SDImageCache sharedImageCache] queryDiskCacheForKey:[url absoluteString] delegate:self userInfo:info]; + [[SDImageCache sharedImageCache] queryDiskCacheForKey:[self cacheKeyForURL:url] delegate:self userInfo:info]; } #endif @@ -313,7 +333,7 @@ static SDWebImageManager *instance; // Store the image in the cache [[SDImageCache sharedImageCache] storeImage:image imageData:downloader.imageData - forKey:[downloader.url absoluteString] + forKey:[self cacheKeyForURL:downloader.url] toDisk:!(options & SDWebImageCacheMemoryOnly)]; } else if (!(options & SDWebImageRetryFailed))