diff --git a/Code/Support/RKDirectory.h b/Code/Support/RKDirectory.h index 6c6d17aa..18318144 100644 --- a/Code/Support/RKDirectory.h +++ b/Code/Support/RKDirectory.h @@ -18,13 +18,28 @@ Returns the path to the Application Data directory for the executing application. On iOS, this is a sandboxed path specific for the executing application. On OS X, this is an application specific path under NSApplicationSupportDirectory (i.e. ~/Application Support). + + @return The full path to the application data directory. */ + (NSString *)applicationDataDirectory; /** Returns a path to the root caches directory used by RestKit for storage. On iOS, this is + a sanboxed path specific for the executing application. On OS X, this is an application + specific path under NSCachesDirectory (i.e. ~/Library/Caches). + @return The full path to the Caches directory. */ + (NSString *)cachesDirectory; +/** + Ensures that a directory exists at a given path by checking for the existence + of the directory and creating it if it does not exist. + + @param path The path to ensure a directory exists at. + @param error On input, a pointer to an error object. + @returns A Boolean value indicating if the directory exists. + */ ++ (BOOL)ensureDirectoryExistsAtPath:(NSString *)path error:(NSError **)error; + @end diff --git a/Code/Support/RKDirectory.m b/Code/Support/RKDirectory.m index adbc02fd..2685c6a9 100644 --- a/Code/Support/RKDirectory.m +++ b/Code/Support/RKDirectory.m @@ -7,12 +7,14 @@ // #import "RKDirectory.h" +#import "NSBundle+RKAdditions.h" #import "RKLog.h" @implementation RKDirectory -+ (NSString *)executableName { - NSString *executableName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleExecutable"]; ++ (NSString *)executableName +{ + NSString *executableName = [[[NSBundle mainBundle] executablePath] lastPathComponent]; if (nil == executableName) { RKLogWarning(@"Unable to determine CFBundleExecutable: storing data under RestKit directory name."); executableName = @"RestKit"; @@ -21,34 +23,21 @@ return executableName; } -+ (NSString *)applicationDataDirectory { ++ (NSString *)applicationDataDirectory +{ #if TARGET_OS_IPHONE NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); - NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil; - if (basePath) { - // In unit tests the Documents/ path may not exist - if(! [[NSFileManager defaultManager] fileExistsAtPath:basePath]) { - NSError* error = nil; - - if(! [[NSFileManager defaultManager] createDirectoryAtPath:basePath withIntermediateDirectories:NO attributes:nil error:&error]) { - RKLogError(@"%@", error); - } - } - - return basePath; - } - - return nil; + return ([paths count] > 0) ? [paths objectAtIndex:0] : nil; #else - NSFileManager* sharedFM = [NSFileManager defaultManager]; + NSFileManager *sharedFM = [NSFileManager defaultManager]; - NSArray* possibleURLs = [sharedFM URLsForDirectory:NSApplicationSupportDirectory + NSArray *possibleURLs = [sharedFM URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask]; - NSURL* appSupportDir = nil; - NSURL* appDirectory = nil; + NSURL *appSupportDir = nil; + NSURL *appDirectory = nil; if ([possibleURLs count] >= 1) { appSupportDir = [possibleURLs objectAtIndex:0]; @@ -57,15 +46,6 @@ if (appSupportDir) { NSString *executableName = [RKDirectory executableName]; appDirectory = [appSupportDir URLByAppendingPathComponent:executableName]; - - - if(![sharedFM fileExistsAtPath:[appDirectory path]]) { - NSError* error = nil; - - if(![sharedFM createDirectoryAtURL:appDirectory withIntermediateDirectories:NO attributes:nil error:&error]) { - RKLogError(@"%@", error); - } - } return [appDirectory path]; } @@ -73,7 +53,8 @@ #endif } -+ (NSString *)cachesDirectory { ++ (NSString *)cachesDirectory +{ #if TARGET_OS_IPHONE return [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]; #else @@ -87,4 +68,25 @@ #endif } ++ (BOOL)ensureDirectoryExistsAtPath:(NSString *)path error:(NSError **)error +{ + BOOL isDirectory; + if ([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory]) { + if (isDirectory) { + // Exists at a path and is a directory, we're good + if (error) *error = nil; + return YES; + } + } + + // Create the directory and any intermediates + NSError *errorReference = (error == nil) ? nil : *error; + if (! [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&errorReference]) { + RKLogError(@"Failed to create requested directory at path '%@': %@", path, errorReference); + return NO; + } + + return YES; +} + @end diff --git a/Tests/RKTestEnvironment.m b/Tests/RKTestEnvironment.m index 3808548a..8fdab6fa 100644 --- a/Tests/RKTestEnvironment.m +++ b/Tests/RKTestEnvironment.m @@ -38,8 +38,24 @@ void RKTestClearCacheDirectory(void) { + (void)initialize { + // Configure fixture bundle NSBundle *fixtureBundle = [NSBundle bundleWithIdentifier:@"org.restkit.unit-tests"]; [RKTestFixture setFixtureBundle:fixtureBundle]; + + // Ensure the required directories exist + BOOL directoryExists; + NSError *error = nil; + directoryExists = [RKDirectory ensureDirectoryExistsAtPath:[RKDirectory applicationDataDirectory] error:&error]; + if (! directoryExists) { + RKLogError(@"Failed to create application data directory. Unable to run tests: %@", error); + NSAssert(directoryExists, @"Failed to create application data directory."); + } + + directoryExists = [RKDirectory ensureDirectoryExistsAtPath:[RKDirectory cachesDirectory] error:&error]; + if (! directoryExists) { + RKLogError(@"Failed to create caches directory. Unable to run tests: %@", error); + NSAssert(directoryExists, @"Failed to create caches directory."); + } } @end