Question

I have a security scope bookmark for a directory, provided by a user via an openDialog request.

I'm trying to create another security scope bookmark for a file inside this directory:

NSURL *musicFolder = /* Secured URL Resolved from a NSData, bookmark not stale */;

if (![musicFolder startAccessingSecurityScopedResource]) {
    NSLog(@"Error accessing bookmark.");
}

NSString *file = @"myfile.txt"; /* This file exists inside the directory */
NSURL *pathURL = [musicFolder URLByAppendingPathComponent:file];

NSError *systemError;
NSData *bookmarkData = [pathURL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
                         includingResourceValuesForKeys:nil
                                          relativeToURL:nil
                                                  error:&systemError];

[musicFolder stopAccessingSecurityScopedResource];

if (!bookmarkData) {
    NSLog(@"%@", systemError);
}

Both bookmarkData and systemError end up nil which is not very useful...

Is this even supported or can you only get valid secured scope bookmarks from the system?

Was it helpful?

Solution

In my test program this works fine. I suspect the append of the file name to the URL is failing in your case (but that's a huge guess) because it's the only thing that seems materially different.

I notice that the url for a security resolved location is: file://localhost/Users/dad/Desktop/TestFolder?applesecurityscope=343335323030663066393432306234363030346263613464636464643130663635353065373030373b30303030303030303b303030303030303030303030303032303b636f6d2e6170706c652e6170702d73616e64626f782e726561642d77726974653b30303030303030313b30313030303030323b303030303030303030326461363838663b2f75736572732f74796c65722f6465736b746f702f74657374666f6c646572

which is the other reason I wonder if the append is the issue.

In my test I have the user choose the folder, create the security scoped bookmark and then save that in user defaults.

Then I quit & relaunch the app and via a menu command I get that bookmark and then resolve it. Then I added a case where I use the resolved bookmark to a folder and make a new bookmark to the file within the folder.

It seems to work fine.


In my test where it's working I'm getting the path to the file like this:

NSURL * resolvedURL = [NSURL URLByResolvingBookmarkData: data
                        options: NSURLBookmarkResolutionWithSecurityScope
                        relativeToURL: nil
                        bookmarkDataIsStale: &isStale
                        error: &error];
... // (error checking)

[resolvedURL startAccessingSecurityScopedResource];

NSArray * files = [[NSFileManager defaultManager] 
                     contentsOfDirectoryAtURL: resolvedURL
                     includingPropertiesForKeys: @[NSURLLocalizedNameKey, NSURLCreationDateKey]
                     options:  NSDirectoryEnumerationSkipsHiddenFiles
                     error: &error];
if ( files != nil )
{
    NSURL * fileURL = [files objectAtIndex: 0]; // hard coded for my quick test
    NSData * newData = [fileURL bookmarkDataWithOptions: NSURLBookmarkCreationWithSecurityScope
                          includingResourceValuesForKeys: nil
                          relativeToURL: nil
                          error: &error];

   if ( newData != nil )
   {
       NSLog(@"it's good!");
   }
   .... // error checking and logging.

if that doesn't get you on the right track, I'm going to need to see more code (you'll probably need to make a simple example).

Note that in my case I'm resolving the bookmark and calling startAccessingSecurityScopedResource even when I just got the url & created the bookmark (when I tried to create a bookmark from the path I'd just acquired from PowerBox (openPanel) it failed with an error 256).

Some configuration details: OS X 10.8.4, Xcode 5 (first public release from today 9/18/2013).

OTHER TIPS

For creating bookmarks for locked files, use NSURLBookmarkCreationSecurityScopeAllowOnlyReadAccess flag combined with NSURLBookmarkCreationWithSecurityScope flag in API call for creating bookmark.

For example:

NSURL* fileURL = [NSURL fileURLWithPath:filePath];
NSError* error = NULL;

NSData* bookmarkData = [fileURL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope|NSURLBookmarkCreationSecurityScopeAllowOnlyReadAccess includingResourceValuesForKeys:nil relativeToURL:nil error:&error];

I have tried this in Mac OS 10.9.5

Following up after reporting the problem with security-scoped bookmarks and locked-files, this is the reply from Apple:

"Also, as you've noticed, creating a security-scoped bookmark requires write access to the target file. That should no longer be the case in OS X Mavericks."

Which would indicate that it is a bug in version of OS X pre-10.9.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top