Trouble creating Security-Scoped Bookmark
Asked Answered
T

1

12

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.

Tsarevitch answered 6/4, 2012 at 12:15 Comment(3)
The start/stop calls are never necessary when making a bookmark. You already got access from NSOpenPanel. The bookmark is saving that access for future runs. And those future runs are where you're going to need to call startAccessingSecurityScopedResource (on the URL you get back from resolving the bookmark).Camarillo
@Camarillo I believe you're right, since in the code I posted I use an NSOpenPanel, but you do need it if you're creating a bookmark from a source other than an NSOpenPanel or NSSavePanel (such as making a new bookmark from an existing one to change its scope). I've updated my post.Tsarevitch
Documentation made my eyes bleed 'til I found "security-scoped bookmarks" and this is really helpful sample code, too. I don't have the power to create a tag, might I suggest we add a tag "security-scoped bookmark"?Preconception
T
10

It turns out I was missing a crucial entitlement, not listed in the UI, but listed in the documentation:

com.apple.security.files.bookmarks.app-scope

Update 12/18/2018

According to this Twitter thread, this entitlement may not be required anymore. Thanks @pkamb for alerting me to this.

Tsarevitch answered 6/4, 2012 at 12:27 Comment(6)
Thanks, the entitlement was what I needed to make this work. Just wanted to add that I don't agree with your update about -startAccessingSecurityScopedResource being not necessary; if I comment this out of my code, I can no longer get access to the resource.Thad
Thank you so much for sharing this solution. I spent ages debugging my code only to discover that this entitlement is necessary in Lion (in Mountain Lion it is not).Yolanthe
Is this entitlement still needed?Recuperate
@Recuperate I have no reason to think it's not anymore - do you?Tsarevitch
Is the http://com.apple.security.files.bookmarks.app -scope entitlement no longer required for security-scoped bookmarks? The docs say it's required, but my testing seems to indicate it's not.Recuperate
related blog post: "I was informed that this entitlement is no longer required, despite it still being listed in the docs. I filed a Feedback for this (FB7405463)."Recuperate

© 2022 - 2024 — McMap. All rights reserved.