NSString
provides a rich set of methods for manipulating strings as file-system paths. You can extract a path’s directory, filename, and extension, expand a tilde expression (such as “~me
”) or create one for the user’s home directory, and clean up paths containing symbolic links, redundant slashes, and references to “.” (current directory) and “..” (parent directory).
NSString
represents paths generically with ‘/’ as the path separator and ‘.’ as the extension separator. Methods that accept strings as path arguments convert these generic representations to the proper system-specific form as needed. On systems with an implicit root directory, absolute paths begin with a path separator or with a tilde expression (“~/...
” or “~user/...
”). Where a device must be specified, you can do that yourself—introducing a system dependency—or allow the string object to add a default device.
You can create a standardized representation of a path using stringByStandardizingPath
. This performs a number of tasks including:
Expansion of an initial tilde expression;
Reduction of empty components and references to the current directory (“//” and “/./”) to single path separators;
In absolute paths, resolution of references to the parent directory (“..”) to the real parent directory;
for example:
NSString *path; |
NSString *standardizedPath; |
path = @"/usr/bin/./grep"; |
standardizedPath = [path stringByStandardizingPath]; |
// standardizedPath: /usr/bin/grep |
path = @"~me"; |
standardizedPath = [path stringByStandardizingPath]; |
// standardizedPath (assuming conventional naming scheme): /Users/Me |
path = @"/usr/include/objc/.."; |
standardizedPath = [path stringByStandardizingPath]; |
// standardizedPath: /usr/include |
path = @"/private/usr/include"; |
standardizedPath = [path stringByStandardizingPath]; |
// standardizedPath: /usr/include |
The following examples illustrate how you can use NSString
’s path utilities and other Cocoa functions to get the user directories.
// assuming that users’ home directories are stored in /Users |
NSString *meHome = [@"~me" stringByExpandingTildeInPath]; |
// meHome = @"/Users/me" |
NSString *mePublic = [@"~me/Public" stringByExpandingTildeInPath]; |
// mePublic = @"/Users/me/Public" |
You can find the home directory for the current user and for a given user with NSHomeDirectory
and NSHomeDirectoryForUser
respectively:
NSString *currentUserHomeDirectory = NSHomeDirectory(); |
NSString *meHomeDirectory = NSHomeDirectoryForUser(@"me"); |
Note that you should typically use the function NSSearchPathForDirectoriesInDomains
to locate standard directories for the current user. For example, instead of:
NSString *documentsDirectory = |
[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; |
you should use:
NSString *documentsDirectory; |
NSArray *paths = NSSearchPathForDirectoriesInDomains |
(NSDocumentDirectory, NSUserDomainMask, YES); |
if ([paths count] > 0) { |
documentsDirectory = [paths objectAtIndex:0]; |
} |
NSString
provides a rich set of methods for manipulating strings as file-system paths, for example:
pathExtension | Interprets the receiver as a path and returns the receiver’s extension, if any. |
stringByDeletingPathExtension | Returns a new string made by deleting the extension (if any, and only the last) from the receiver. |
stringByDeletingLastPathComponent | Returns a new string made by deleting the last path component from the receiver, along with any final path separator. |
Using these and related methods described in NSString Class Reference, you can extract a path’s directory, filename, and extension, as illustrated by the following examples.
NSString *documentPath = @"~me/Public/Demo/readme.txt"; |
NSString *documentDirectory = [documentPath stringByDeletingLastPathComponent]; |
// documentDirectory = @"~me/Public/Demo" |
NSString *documentFilename = [documentPath lastPathComponent]; |
// documentFilename = @"readme.txt" |
NSString *documentExtension = [documentPath pathExtension]; |
// documentExtension = @"txt" |
You can find possible expansions of file names using completePathIntoString:caseSensitive:matchesIntoArray:filterTypes:
. For example, given a directory ~/Demo
that contains the following files:
ReadMe.txt readme.html readme.rtf recondite.txt test.txt
you can find all possible completions for the path ~/Demo/r
as follows:
NSString *partialPath = @"~/Demo/r"; |
NSString *longestCompletion; |
NSArray *outputArray; |
unsigned allMatches = [partialPath completePathIntoString:&longestCompletion |
caseSensitive:NO |
matchesIntoArray:&outputArray |
filterTypes:NULL]; |
// allMatches = 3 |
// longestCompletion = @"~/Demo/re" |
// outputArray = (@"~/Demo/readme.html", "~/Demo/readme.rtf", "~/Demo/recondite.txt") |
You can find possible completions for the path ~/Demo/r
that have an extension “.txt” or “.rtf” as follows:
NSArray *filterTypes = [NSArray arrayWithObjects:@"txt", @"rtf", nil]; |
unsigned textMatches = [partialPath completePathIntoString:&outputName |
caseSensitive:NO |
matchesIntoArray:&outputArray |
filterTypes:filterTypes]; |
// allMatches = 2 |
// longestCompletion = @"~/Demo/re" |
// outputArray = (@"~/Demo/readme.rtf", @"~/Demo/recondite.txt") |
Last updated: 2009-10-15