Create folder/directory in Objective-C/cocoa
I have this code for creating a folder/directory in Objective-C/cocoa.
if(![fileManager fileExistsAtPath:directory isDirectory:&isDir])
if(![fileManager createDirectoryAtPath:directory attributes:nil])
NSLog(@"Error: Create folder failed %@", directory);
It works fine, but I got creatDirectoryAtPath:attributes is deprecated
warning message.
What's the newest way of making a directory builder in Cocoa/Objective-c?
SOLVED
BOOL isDir;
NSFileManager *fileManager= [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:directory isDirectory:&isDir])
if(![fileManager createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:NULL])
NSLog(@"Error: Create folder failed %@", directory);
Found in the documentation:
-[NSFileManager createDirectoryAtPath:withIntermediateDirectories:attributes:error:]
Your solution is correct, though Apple includes an important note within NSFileManager.h
:
/* The following methods are of limited utility. Attempting to predicate behavior
based on the current state of the filesystem or a particular file on the
filesystem is encouraging odd behavior in the face of filesystem race conditions.
It's far better to attempt an operation (like loading a file or creating a
directory) and handle the error gracefully than it is to try to figure out ahead
of time whether the operation will succeed. */
- (BOOL)fileExistsAtPath:(NSString *)path;
- (BOOL)fileExistsAtPath:(NSString *)path isDirectory:(BOOL *)isDirectory;
- (BOOL)isReadableFileAtPath:(NSString *)path;
- (BOOL)isWritableFileAtPath:(NSString *)path;
- (BOOL)isExecutableFileAtPath:(NSString *)path;
- (BOOL)isDeletableFileAtPath:(NSString *)path;
Essentially, if multiple threads/processes are modifying the file system simultaneously the state could change in between calling fileExistsAtPath:isDirectory:
and calling createDirectoryAtPath:withIntermediateDirectories:
, so it is superfluous and possibly dangerous to call fileExistsAtPath:isDirectory:
in this context.
For your needs and within the limited scope of your question it likely would not be a problem, but the following solution is both simpler and offers less of a chance of future issues arising:
NSFileManager *fileManager= [NSFileManager defaultManager];
NSError *error = nil;
if(![fileManager createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:&error]) {
// An error has occurred, do something to handle it
NSLog(@"Failed to create directory \"%@\". Error: %@", directory, error);
}
Also note from Apple's documentation:
Return Value
YES if the directory was created, YES if createIntermediates is set and the directory already exists), or NO if an error occurred.
So, setting createIntermediates
to YES
, which you already do, is a de facto check of whether the directory already exists.
Thought I'd add to this and mention some more from the documentation about using the +defaultManager method:
In iOS and Mac OS X v 10.5 and later you should consider using [[NSFileManager alloc] init] rather than the singleton method defaultManager. Instances of NSFileManager are considered thread-safe when created using [[NSFileManager alloc] init].
You may prefer to work with the NSFileManager
method:
createDirectoryAtURL:withIntermediateDirectories:attributes:error:
It works with URL's instead of path strings.