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;
}
@endLet 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