Creating a security scope bookmark for a file from

2019-01-23 16:53发布

问题:

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?

回答1:

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).



回答2:

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



回答3:

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.