14

I have a Cocoa application that stores a reference to multimedia files (images, videos, etc) on the user's computer. I'm wondering if there is a way to get a reference to that file other that using a file path so that if the user moves that file to a different folder on their computer, I would still know where it is. I'm currently storing the array of file paths that are passed back from the standard Cocoa open dialogue:

-(void)addMultimediaDidEnd:(NSOpenPanel*)sheet
           returnCode:(int)returnCode
          contextInfo:(NSString *)contextInfo 
{   
    if(returnCode == NSOKButton) {
        [sheet orderOut:nil];
        [self saveFiles:[sheet filenames]];
    }
}
Austin
  • 4,638
  • 7
  • 41
  • 60

2 Answers2

19

In OS X 10.6 (Snow Leopard), an NSURL can be converted to a file reference URL (using -[NSURL fileReferenceURL]) which references a file across moves while your application is running. If you want to persist this file reference, use +[NSURL writeBookmarkData:toURL:options:error:] passing the bookmark data generated with -[NSURL bookmarkDataWithOptions:includingResourceValuesForKeys:relativeToURL:error]. The bookmark can be resolved later with +[NSURL URLByResolvingBookmarkData:options:relativeToURL:bookmarkDataIsStale:error:] passing the bookmark data returned from +[NSURL bookmarkDataWithContentsOfURL:error:].

Prior to OS X 10.6, the same functionality (minus some network aware niceties) is available via the AliasManager, a Carbon-era interface to the OS X file alias system. There are a couple of Objective-C wrappers on top of the Alias Manager that make using it from Cocoa much nicer. My favorite is Wolf Rentzsch's additions to Chris Hanson's BDAlias (available on github).

Barry Wark
  • 107,306
  • 24
  • 181
  • 206
9

Here's a quick example of using bookmarks to track files across moves:

- (NSData *)bookmarkFromURL:(NSURL *)url {
    NSData *bookmark = [url bookmarkDataWithOptions:NSURLBookmarkCreationMinimalBookmark
                     includingResourceValuesForKeys:NULL
                                      relativeToURL:NULL
                                              error:NULL];
    return bookmark;
}

- (NSURL *)urlFromBookmark:(NSData *)bookmark {
    NSURL *url = [NSURL URLByResolvingBookmarkData:bookmark
                                           options:NSURLBookmarkResolutionWithoutUI
                                     relativeToURL:NULL
                               bookmarkDataIsStale:NO
                                             error:NULL];
    return url;
}

From https://github.com/ptrsghr/FileWatcher/blob/master/FileWatcherExample/Classes/FileWatcher.m

rgbrgb
  • 1,146
  • 1
  • 11
  • 17
  • does this work in sandbox ? Or do I have to ask for special permissions ? – cocoa coder Nov 19 '12 at 18:59
  • I know you posted on GitHub but I'll leave this here for completeness. I believe it should work in sandbox mode (https://github.com/ptrsghr/FileWatcher/pull/1#commits-pushed-02a521c). Let me know if you run into any issues. – rgbrgb Nov 24 '12 at 18:08