Storing/Accessing files in your app folder for private or public use.

When you do any kind of file processing in iOS, you probably want to store the original file and/or the new file somewhere.

Public or Private?

You can store files in your apps ‘sandbox’ either for private use, where only your app can access it, or public use, where iTunes can see the files and will let you add/remove files.

For public use, we grab the NSDocumentDirectory path:

	NSArray *publicPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	NSString *publicDocumentsPath = [publicPaths objectAtIndex:0];

(You’ll also have to add a property called ‘Application supports iTunes file sharing’, set to TRUE in your Custom iOS Target Properties section to get this working.)

For private use, we grab the NSLibraryDirectory path:

    NSArray *privatePaths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
    NSString *privateDocumentsPath = [privatePaths objectAtIndex:0];

Getting a directories contents

Once you’ve got the appropriate path, its easy to iterate through the contents at that location returned by contentsOfDirectoryAtPath:error:

    NSArray *files=[[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL];
    for (NSString *file in files) {
        NSString *filePath=[path stringByAppendingPathComponent:file];
        NSLog(@"Path for file '%@' at '%@'",file,filePath);
    }

Reading, Writing, and ArithmeticDeleting

You can see if a file/directory exists at a given path with fileExistsAtPath:isDirectory:

    BOOL isDir;
    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDir]) {
        NSLog(@"File '%@' exists as %@",filePath,isDir?@"Directory":"File");
    }

You can read a file

    NSData *data;
    if ((data=[[NSFileManager defaultManager] contentsAtPath:filePath])==nil) {
        NSLog(@"Couldn't get contents of file at '%@',filePath);
    }

You can create a directory with createDirectoryAtPath:withIntermediateDirectories:attributes:error:, which optionally creates any necessary intermediate directories for you:

    if ([[NSFileManager defaultManager] createDirectoryAtPath:folderPath
                                  withIntermediateDirectories:YES
                                                   attributes:nil error:NULL]==NO) {
        NSLog(@"Error creating folder '%@'\n",folderPath);
        return NO;
    }

You can write to a file with createFileAtPath:contents:attributes:

    NSData *data=...; // data you want to write to the file
    if ([[NSFileManager defaultManager] createFileAtPath:filePath contents:data attributes:nil]==NO) {
        NSLog(@"Error writing file.");
    }

You rename/move files and directories with moveItemAtPath:toPath:error:

    if ([[NSFileManager defaultManager] moveItemAtPath:oldFile toPath:newFile error:NULL]==NO) {
        NSLog(@"Error moving file from '%@' to '%@'\n",oldFile,newFile);
    }

You delete a file/directory with removeItemAtPath:error:

    if ([[NSFileManager defaultManager] removeItemAtPath:filePath error:NULL]==NO) {
        NSLog(@"Error deleting '%@'\n",filePath);
        return NO;
    }

Caveat

There are many other functions in the NSFileManager class that you can use.

For simplicity sake, I’ve used NULL’s for all the errors. In actual code you should handle errors appropriately.