Resolving Aliases

Unlike symbolic links, Mac OS X aliases are not handled automatically by Cocoa. This article explains how to resolve aliases in a path.

Paths returned by Cocoa classes such as NSOpenPanel may contain alias references that you must resolve before using. To resolve aliases in a path contained in an NSString, you need to first convert the string to a URL, convert the URL to an FSRef, resolve the alias, and reverse the series of conversions to yield another NSString. To perform the necessary conversions, you need to use the URL and alias services provided in <CoreServices/CoreServices.h>. The following code fragment uses FSResolveAliasFile to resolve any aliases in path and stores the resolved path in resolvedPath:

NSString *path = <#Get a suitable path#>;
NSString *resolvedPath = nil;
 
CFURLRef url = CFURLCreateWithFileSystemPath
                   (kCFAllocatorDefault, (CFStringRef)path, kCFURLPOSIXPathStyle, NO);
if (url != NULL)
{
    FSRef fsRef;
    if (CFURLGetFSRef(url, &fsRef))
    {
        Boolean targetIsFolder, wasAliased;
        OSErr err = FSResolveAliasFile (&fsRef, true, &targetIsFolder, &wasAliased);
        if ((err == noErr) && wasAliased)
        {
            CFURLRef resolvedUrl = CFURLCreateFromFSRef(kCFAllocatorDefault, &fsRef);
            if (resolvedUrl != NULL)
            {
                resolvedPath = (NSString*)
                        CFURLCopyFileSystemPath(resolvedUrl, kCFURLPOSIXPathStyle);
                CFRelease(resolvedUrl);
            }
        }
    }
    CFRelease(url);
}
 
if (resolvedPath == nil)
{
    resolvedPath = [[NSString alloc] initWithString:path];
}

The second argument to FSResolveAliasFile specifies whether you want the function to resolve all aliases in a chain (for example, an alias file that refers to an alias file and so on), stopping only when it reaches the target file.