While working on an iPhone application which makes use of remote data and remote image assets, I realised I needed an object that could quickly and easily cache remote images in the app’s local sandboxed “Documents” folder. To be honest, I kind of feel like I reinvented someone’s wheel here, but I got exactly what I wanted – a small class (singleton) that provides full remote image (not limited to images though) caching within the sandboxed environment on an iPhone.
The class is implemented as a singleton since I can’t imagine one would want multiple storage caches running around interfering with each other.
ImageCache.h
The class is implemented as a singleton since I can’t imagine one would want multiple storage caches running around interfering with each other.
ImageCache.h
// // ImageCache.h // // Created by Tariq Mohammad on 03/03/11. // Copyright 2011 __MyCompanyName__. All rights reserved. // #importImageCache.m@interface ImageCache : NSObject { NSString *documentsDirectory; NSString *cacheFileUrl; NSMutableDictionary *dictCache; } @property (nonatomic, retain) NSDictionary *dictCache; + (ImageCache*) instance; - (BOOL) isRemoteFileCached:(NSString*)url; - (NSData*) getCachedRemoteFile:(NSString*)url; - (BOOL) addRemoteFileToCache:(NSString*)url withData:(NSData*)data; @end
// // ImageCache.m// // Created by Tariq Mohammad on 03/03/11. // Copyright 2011 __MyCompanyName__. All rights reserved. // #import "ImageCache.h" #define kDefaultCacheFile @"imagecache.plist" ////////////////////////////////////////////////////////////////////////////////////////////////// @interface ImageCache (private) - (NSString*) makeKeyFromUrl:(NSString*)url; @end//private ImageCache interface ////////////////////////////////////////////////////////////////////////////////////////////////// static ImageCache *sharedInstance = nil; ////////////////////////////////////////////////////////////////////////////////////////////////// @implementation ImageCache @synthesize dictCache; //////////////////////////////////////////////////////////////////////////////// - (id)init { if ( (self = [super init]) ) { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); documentsDirectory = [paths objectAtIndex:0]; // the path to the cache map cacheFileUrl = [documentsDirectory stringByAppendingPathComponent:kDefaultCacheFile]; [cacheFileUrl retain]; dictCache = [[NSDictionary alloc] initWithContentsOfFile:cacheFileUrl]; if ( dictCache == nil ) { dictCache = [[NSMutableDictionary alloc] init]; } } return self; } //////////////////////////////////////////////////////////////////////////////// - (void)dealloc { [cacheFileUrl release]; [dictCache release] [super dealloc]; } //////////////////////////////////////////////////////////////////////////////// + (ImageCache*) instance { @synchronized(self) { if ( sharedInstance == nil ) { sharedInstance = [[ImageCache alloc] init]; } } return sharedInstance; } //////////////////////////////////////////////////////////////////////////////// - (BOOL) isRemoteFileCached:(NSString*)url { NSString *imageFilename = [dictCache valueForKey:[self makeKeyFromUrl:url]]; return (imageFilename != nil); } //////////////////////////////////////////////////////////////////////////////// - (NSData*) getCachedRemoteFile:(NSString*)url { NSString *imageFilename = [dictCache valueForKey:[self makeKeyFromUrl:url]]; NSData *data = nil; if ( imageFilename != nil ) { data = [NSData dataWithContentsOfFile:imageFilename]; } return data; } //////////////////////////////////////////////////////////////////////////////// - (BOOL) addRemoteFileToCache:(NSString*)url withData:(NSData*)data { BOOL result = NO; NSString *imageFilename = [url lastPathComponent]; if ( imageFilename != nil ) { // the path to the cached image file NSString *cachedImageFileUrl = [documentsDirectory stringByAppendingPathComponent:imageFilename]; result = [data writeToFile:cachedImageFileUrl atomically:YES]; if ( result == YES ) { // add the cached file to the dictionary [dictCache setValue:cachedImageFileUrl forKey:[self makeKeyFromUrl:url]]; [dictCache writeToFile:cacheFileUrl atomically:YES]; } } return result; } //////////////////////////////////////////////////////////////////////////////// #pragma mark - #pragma mark Private Methods - (NSString*) makeKeyFromUrl:(NSString*)url { NSString *key = [url stringByReplacingOccurrencesOfString:@"/" withString:@"."]; key = [key stringByReplacingOccurrencesOfString:@":" withString:@"."]; return key; } @end
Let me know if you find this useful, or have suggestions on improving it.
piece of crap!
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDeleteHow to use this class
ReplyDeleteThese are wrapper classes. It should be accessible like the same way you access other wrapper classes
ReplyDelete