Skip to content

Instantly share code, notes, and snippets.

@benzamin benzamin/BBFileManager.h
Last active Aug 20, 2017

Embed
What would you like to do?
Utility Class for basic file caching and file manipulation of documentsdirectory if iOS.
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface BBFileManager : NSObject
//-------------------- File caching ------------------
/**
* Caches a NSDictionary in the cache for a certain period of time
* @param dict The NSDictionary which need to be cached
* @param name The name of the cached dictionary
* @param validity How many seconds(NSTimerInterval) you want to cache the dictionary
*/
+(void)cacheNewDictionary:(NSDictionary*)dict withName:(NSString*)name validity:(NSTimeInterval)timeInterval;
/**
* Caches a NSArray in the cache for a certain period of time
* @param arr The NSArray which need to be cached
* @param name The name of the cached array
* @param validity How many seconds(NSTimerInterval) you want to cache the array
*/
+(void)cacheNewArray:(NSArray*)arr withName:(NSString*)name validity:(NSTimeInterval)timeInterval;
/**
* Returns a previously cached NSArray
* @param name The name of the cached array
*/
+(NSArray*)getCachedArrayWithName:(NSString*)name;
/**
* Returns a previously cached NSDictionary
* @param name The name of the cached dictionary
*/
+(NSDictionary*)getCachedDictionaryWithName:(NSString*)name;
/**
* Checks for any invalid/outdated cache file and remove them
* @warning Use it wisely, cause all the cached but invalidated files need to be redownloaded
*/
+(void)sanitizeCache;
//-----------------File Manipulation---------------------
/**
* Returns the full path of a file in the documents directory. In fact, the file name is appended at the end of the documentsdirectory path
* @param name The name of the file
* @return the full path of the file in documentsdirectory
*/
+(NSString*)getFilePathFromDocumentsDirectoryNamed:(NSString*)fileName;
/**
* returns the full path of documents diretory
* @return the full path of the documentsdirectory
*/
+(NSString*)getDocumentsDirectoryPath;
/**
* Saved a dictionary in documents directory
* @param dict The NSDictionary which need to be saved
* @param name The name of the saved dictionary
* @return true if save was successfull, otherwise false
*/
+(BOOL)saveDictionary:(NSDictionary*)dict withName:(NSString*)name;
/**
* Gets a saved NSDictionary for documents directory
* @param name The name of saved dictionary need to retrive
* @return the NSDictionary if found, otherwise nil
*/
+(NSDictionary*)getDictionaryWithName:(NSString*)name;
/**
* Retrive a previously saved UIImage from documents directory
* @param name The name of the saved dictionary
* @return saved image if found in documentsdirectory, otherwise nil
*/
+(UIImage*)getImageWithName:(NSString*)name;
/**
* Saves a Image in the documents directory
* @param name The name of the image
* @param image The image that need to be saved
* @return true if save was successful, otherwise false
*/
+(BOOL)saveImage:(UIImage*)image WithName:(NSString*)name;
/**
* Retrive a previously saved file from documents directory
* @param name The name of the saved file
* @return saved file if found in documentsdirectory, otherwise nil
*/
+(NSURL*)getFileURLWithName:(NSString*)name;
/**
* Remove a previously saved file
* @param path The path of the file
* @return true if deletion was successful, otherwise false
*/
+(BOOL)removeFileAtPath:(NSString*)path;
@end
#import "BBFileManager.h"
#define CACHE_INFO_DICTIONARY_NAME @"BBcacheDictionary.plist"
#define CACHE_FILE_CREATION_DATE_KEY @"BBcasheCreationDate"
#define CACHE_FILE_NAME_KEY @"BBcasheFileName"
#define CACHE_FILE_VALIDITY_KEY @"BBcasheFileValidityInDays"
#define CACHE_FILE_TIMESTAMP_SEPERATOR @"*##*"
@implementation BBFileManager
+(NSString*)getFilePathFromDocumentsDirectoryNamed:(NSString*)fileName
{
NSString *documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectoryPath error:nil];
for (NSString *tString in dirContents)
{
if ([tString isEqualToString:fileName])
{
return [NSString stringWithFormat:@"%@/%@",documentsDirectoryPath, tString] ;
}
}
return nil;
}
+(BOOL)removeFileAtPath:(NSString*)path
{
return [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
}
+(NSString*)getDocumentsDirectoryPath
{
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
}
+(BOOL)saveDictionary:(NSDictionary*)dict withName:(NSString*)name
{
NSString *path = [[BBFileManager getDocumentsDirectoryPath] stringByAppendingPathComponent:name];
return [dict writeToFile:path atomically:YES];
}
+(NSDictionary*)getDictionaryWithName:(NSString*)name
{
NSString *path = [[BBFileManager getDocumentsDirectoryPath] stringByAppendingPathComponent:name];
return [NSDictionary dictionaryWithContentsOfFile:path];
}
+(NSArray*)getArrayWithName:(NSString*)name
{
NSString *path = [[BBFileManager getDocumentsDirectoryPath] stringByAppendingPathComponent:name];
return [NSArray arrayWithContentsOfFile:path];
}
+ (UIImage*)getImageWithName:(NSString*)name{
NSString *savedImagePath = [[BBFileManager getDocumentsDirectoryPath] stringByAppendingPathComponent:name];
return [UIImage imageWithContentsOfFile:savedImagePath];
}
+ (BOOL)saveImage:(UIImage*)image WithName:(NSString*)name{
NSString *savedImagePath = [[BBFileManager getDocumentsDirectoryPath] stringByAppendingPathComponent:name];
NSData *imageData = UIImagePNGRepresentation(image);
return [imageData writeToFile:savedImagePath atomically:YES];
}
+(NSURL*)getFileURLWithName:(NSString*)name
{
return [NSURL fileURLWithPath:[[BBFileManager getDocumentsDirectoryPath] stringByAppendingPathComponent:name]];
}
//cashing methods
+(void)cacheNewDictionary:(NSDictionary*)dict withName:(NSString*)name validity:(NSTimeInterval)timeInterval
{
NSString *filename = [BBFileManager getFormattedCacheFileNameForName:name];
NSString *path = [[BBFileManager getDocumentsDirectoryPath] stringByAppendingPathComponent:filename];
if([dict writeToFile:path atomically:YES])
{
[BBFileManager addNewCacheEntryForFileName:filename validity:timeInterval];
}
}
+(void)cacheNewArray:(NSArray*)arr withName:(NSString*)name validity:(NSTimeInterval)timeInterval
{
NSString *filename = [BBFileManager getFormattedCacheFileNameForName:name];
NSString *path = [[BBFileManager getDocumentsDirectoryPath] stringByAppendingPathComponent:filename];
if([arr writeToFile:path atomically:YES])
{
[BBFileManager addNewCacheEntryForFileName:filename validity:timeInterval];
}
}
+(void)addNewCacheEntryForFileName:(NSString*)name validity:(NSTimeInterval)timeInterval
{
NSMutableDictionary *cacheDict = [NSMutableDictionary dictionaryWithDictionary:[BBFileManager getDictionaryWithName:CACHE_INFO_DICTIONARY_NAME]];
NSNumber *validityInDays = [NSNumber numberWithDouble:timeInterval];
NSDate *createdDate = [NSDate date];
NSDictionary *newEntry = @{CACHE_FILE_NAME_KEY:name, CACHE_FILE_CREATION_DATE_KEY:createdDate, CACHE_FILE_VALIDITY_KEY:validityInDays};
[cacheDict setObject:newEntry forKey:name];
[BBFileManager saveDictionary:cacheDict withName:CACHE_INFO_DICTIONARY_NAME];
}
+(NSArray*)getCachedArrayWithName:(NSString*)name
{
NSMutableDictionary *cacheDict = [NSMutableDictionary dictionaryWithDictionary:[BBFileManager getDictionaryWithName:CACHE_INFO_DICTIONARY_NAME]];
BOOL cacheFileChanged = NO;
for(NSString* key in cacheDict.allKeys) {
NSArray *splitArr = [key componentsSeparatedByString:CACHE_FILE_TIMESTAMP_SEPERATOR];
if(splitArr > 0 && [splitArr[0] isEqualToString:name]) {
NSDictionary *fileDict = cacheDict[key];
NSDate *creationDate = (NSDate*)[fileDict valueForKey:CACHE_FILE_CREATION_DATE_KEY];
double validity = [[fileDict valueForKey:CACHE_FILE_VALIDITY_KEY] doubleValue];
if(![BBFileManager didFileExpiredForvalidity:validity creationDate:creationDate]){
return [NSArray arrayWithArray:[BBFileManager getArrayWithName:key]];
}
else{
NSString *filePath = [BBFileManager getFilePathFromDocumentsDirectoryNamed:fileDict[CACHE_FILE_NAME_KEY]];
if(filePath) [BBFileManager removeFileAtPath:filePath];
[cacheDict removeObjectForKey:key];
cacheFileChanged = YES;
}
}
}
if(cacheFileChanged){
[BBFileManager saveDictionary:cacheDict withName:CACHE_INFO_DICTIONARY_NAME];
}
return nil;
}
+(NSDictionary*)getCachedDictionaryWithName:(NSString*)name
{
NSMutableDictionary *cacheDict = [NSMutableDictionary dictionaryWithDictionary:[BBFileManager getDictionaryWithName:CACHE_INFO_DICTIONARY_NAME]];
BOOL cacheFileChanged = NO;
for(NSString* key in cacheDict.allKeys){
NSArray *splitArr = [key componentsSeparatedByString:CACHE_FILE_TIMESTAMP_SEPERATOR];
if(splitArr > 0 && [splitArr[0] isEqualToString:name]){
NSDictionary *fileDict = cacheDict[key];
NSDate *creationDate = (NSDate*)[fileDict valueForKey:CACHE_FILE_CREATION_DATE_KEY];
double validity = [[fileDict valueForKey:CACHE_FILE_VALIDITY_KEY] doubleValue];
if(![BBFileManager didFileExpiredForvalidity:validity creationDate:creationDate]){
return [NSDictionary dictionaryWithDictionary:[BBFileManager getDictionaryWithName:key]];
}
else{
NSString *filePath = [BBFileManager getFilePathFromDocumentsDirectoryNamed:fileDict[CACHE_FILE_NAME_KEY]];
if(filePath) [BBFileManager removeFileAtPath:filePath];
[cacheDict removeObjectForKey:key];
cacheFileChanged = YES;
}
}
}
if(cacheFileChanged){
[BBFileManager saveDictionary:cacheDict withName:CACHE_INFO_DICTIONARY_NAME];
}
return nil;
}
+(void)sanitizeCache{
NSMutableDictionary *cacheDict = [NSMutableDictionary dictionaryWithDictionary:[BBFileManager getDictionaryWithName:CACHE_INFO_DICTIONARY_NAME]];
BOOL cacheFileChanged = NO;
for(NSString* key in cacheDict.allKeys){
NSDictionary *fileDict = cacheDict[key];
NSDate *creationDate = (NSDate*)[fileDict valueForKey:CACHE_FILE_CREATION_DATE_KEY];
double validity = [[fileDict valueForKey:CACHE_FILE_VALIDITY_KEY] doubleValue];
if([BBFileManager didFileExpiredForvalidity:validity creationDate:creationDate]){
NSString *filePath = [BBFileManager getFilePathFromDocumentsDirectoryNamed:fileDict[CACHE_FILE_NAME_KEY]];
if(filePath) [BBFileManager removeFileAtPath:filePath];
[cacheDict removeObjectForKey:key];
cacheFileChanged = YES;
}
}
if(cacheFileChanged){
[BBFileManager saveDictionary:cacheDict withName:CACHE_INFO_DICTIONARY_NAME];
}
}
#pragma mark - Utility methods
+(BOOL)didFileExpiredForvalidity:(NSTimeInterval)timeInteral creationDate:(NSDate*)creationDate
{
NSDate * fileExpireDate = [creationDate dateByAddingTimeInterval:timeInteral];
NSDate * now = [NSDate date];
NSComparisonResult result = [now compare:fileExpireDate];
switch (result)
{
case NSOrderedAscending:{
//NSLog(@"%@ is in future from %@", fileExpireDate, now);
return NO;
} break;
case NSOrderedDescending:{
//NSLog(@"%@ is in past from %@", fileExpireDate, now);
}break;
case NSOrderedSame:
{
//NSLog(@"%@ is the same as %@", fileExpireDate, now);
} break;
default: {
//NSLog(@"erorr dates %@, %@", fileExpireDate, now);
} break;
}
return YES;
}
+(NSString*)getFormattedCacheFileNameForName:(NSString*)name
{
NSTimeInterval interval = [[NSDate date] timeIntervalSince1970];
return [NSString stringWithFormat:@"%@%@%f.dat", name, CACHE_FILE_TIMESTAMP_SEPERATOR ,interval];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.