I'm converting my Lion app to use the App Sandbox. I'm trying to make use of the security-scoped bookmarks feature introduced in 10.7.3 to allow persistent access to a folder. The code I have below returns a nil bookmark, and produces the following log message: XPC couldn't look up the Mach service for scoped bookmarks agent
.
I set the User Selected File Access
entitlement to Read/Write Access
, and also tried with and without the surrounding ..AccessingSecurityScopedResource
calls.
I think I'm doing everything right according to the documentation, so I'd appreciate any pointers. The code was working to retrieve a plain URL before I began sandboxing the app.
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
[openPanel setCanChooseFiles:NO];
[openPanel setCanChooseDirectories:YES];
[openPanel setAllowsMultipleSelection:NO];
NSInteger result = [openPanel runModal];
if( result == NSFileHandlingPanelCancelButton ) {
return;
}
NSArray *urls = [openPanel URLs];
if( urls != nil && [urls count] == 1 ) {
NSURL *url = [urls objectAtIndex:0];
NSData *bookmark = nil;
NSError *error = nil;
bookmark = [url bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
includingResourceValuesForKeys:nil
relativeToURL:nil // Make it app-scoped
error:&error];
if (error) {
NSLog(@"Error creating bookmark for URL (%@): %@", url, error);
[NSApp presentError:error];
}
NSLog(@"bookmark: %@", bookmark);
}
Update (x3)
Now that I got it working, I can verify that the calls to -startAccessingSecurityScopedResource
and -stopAccessingSecurityScopedResource
are not necessary in the code above, since the Powerbox grants access to the resource after the user selects it in the NSOpenPanel
.
If you're creating a bookmark from another security-scoped URL, such as making a document-scoped bookmark from an app-scoped bookmark created in another app session, then you need to get access to the file first.
NSOpenPanel
, but you do need it if you're creating a bookmark from a source other than anNSOpenPanel
orNSSavePanel
(such as making a new bookmark from an existing one to change its scope). I've updated my post. – Tsarevitch