< Previous PageNext Page > Hide TOC

Locating Directories on the System

When you programmatically locate files and directories in the file system—such as for copy, move, and delete operations—you should always try to avoid hard-coded paths in your code. (The document “Portable File-System Operations” gives the reasons for this recommendation.) As much as possible, obtain the directory locations used in file-system operations through functions provided by Cocoa or other application environments.

Ideally, you should use the Cocoa functions and constants defined in NSPathUtilities.h. They are easier to use and more efficient in Cocoa code. The primary function for obtaining paths to standard directories is NSSearchPathForDirectoriesInDomains. This function takes three parameters:

The NSSearchPathForDirectoriesInDomains function returns an array of paths (as NSString objects). In general this function returns multiple values if the parameters imply multiple locations. However, don’t make any assumptions as to the number of paths returned. Some domains or locations might be made obsolete over time, or other new domains or locations might be added (while preserving the older ones); in either case, the number of paths in the returned array might increase or decrease. Simply look at all of the returned values if you want to enumerate all of the files. If you just want to copy or move a file to a location and multiple paths are returned, use the first one in the array.

Listing 1 illustrates how you might use NSSearchPathForDirectoriesInDomains before moving a file with NSFileManager’s copyItemAtPath:toPath:error: (prior to Mac OS X v10.5, you would use copyPath:toPath:handler:).

Listing 1  Using NSSearchPathForDirectoriesInDomains

- (BOOL)makeUserCopyOfFile(NSString* sourcePath) error:(NSError **)outError
{
    NSArray *paths;
    NSFileManager *mgr = [NSFileManager defaultManager];
 
    paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    if ([paths count] > 0)
    {
        // only copying one file
        NSString *destinationPath = [[paths objectAtIndex:0]
                        stringByAppendingPathComponent:[sourcePath lastPathComponent]];
        if (![mgr copyItemAtPath:toPath:destinationPath error:outError])
        {
            return NO;
        }
        return YES;
    }
    // create a suitable NSError object to return in outError
    return NO;
}

The NSPathUtilities.h header file also defines other functions that you can use to obtain the current logged-in user’s home directory (NSHomeDirectory), the home directory of a specified user (NSHomeDirectoryForUser), and the directory used for temporary storage (NSTemporaryDirectory).

You can also use functions of the Carbon Folder Manager to get paths to standard directories in the file system. (The Folder Manager is defined in Folders.h in the Carbon Core framework, which is a subframework of the Core Services umbrella framework.)

Important: Carbon Folder Manager functions are not available on iPhone.

Perhaps the most useful function for Cocoa programs is FSFindFolder. This function (like other Folder Manager functions) returns the found path typed as a FSRef. To use this value in Cocoa, you must first convert it to a Core Foundation CFURL object, then to a CFString object, and finally to an NSString object. “Using FSFindFolder” shows how you might call FSFindFolder and convert the returned value to obtain a path used in moving a file to the user’s desktop.

Listing 2  Using FSFindFolder

- (BOOL)moveFileToUserDesktop:(NSString *filePath) error:(NSError **)outError
{
 
    CFURLRef        desktopURL;
    FSRef           desktopFolderRef;
    CFStringRef     desktopPath;
    OSErr           err;
    NSFileManager   *mgr = [NSFileManager defaultManager];
 
    err = FSFindFolder(kUserDomain, kDesktopFolderType, kDontCreateFolder, &desktopFolderRef);
    if (err == noErr)
    {
        desktopURL = CFURLCreateFromFSRef(kCFAllocatorSystemDefault, &desktopFolderRef);
        if (desktopURL)
        {
            desktopPath = CFURLCopyFileSystemPath (desktopURL, kCFURLPOSIXPathStyle);
            NSString *destinationPath = [(NSString *)desktopPath
                             stringByAppendingPathComponent:[filePath lastPathComponent]];
            if (![mgr moveItemAtPath:filePath toPath:destinationPath error:outError])
            {
                return NO;
            }
            if (desktopPath)
            {
                CFRelease(desktopPath);
            }
            CFRelease(desktopURL);
            return YES;
        }
        else
        {
            // create a suitable NSError object to return in outError
            return NO;
 
        }
    }
    // create a suitable NSError object to return in outError
    return NO;
}

Similar to Cocoa’s NSSearchPathForDirectoriesInDomains function, the FSFindFolder function includes as parameters constants specifying standard directories and file-system domains.

Moving files to the Trash: To move items to the Trash, you should use NSWorkspace’s performFileOperation:source:destination:files:tag method using the operation NSWorkspaceRecycleOperation.



< Previous PageNext Page > Hide TOC


© 1997, 2009 Apple Inc. All Rights Reserved. (Last updated: 2009-03-05)


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.