从包含它的目录之一为文件创建安全范围书签

时间:2013-09-10 05:03:35

标签: cocoa sandbox appstore-sandbox

我有一个目录的安全范围书签,由用户通过openDialog请求提供。

我正在尝试为此目录中的文件创建另一个安全范围书签:

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);
}

bookmarkDatasystemError结尾都是零,这不是很有用......

这是否支持,或者您只能从系统获得有效的安全范围书签?

3 个答案:

答案 0 :(得分:6)

在我的测试程序中,这很好用。我怀疑在你的情况下文件名附加到URL是失败的(但这是一个巨大的猜测),因为它是唯一看起来有实质性不同的东西。

我注意到了一个安全解决位置的URL是:文件://本地主机/用户/爸爸/桌面/ TestFolder applesecurityscope = 343335323030663066393432306234363030346263613464636464643130663635353065373030373b30303030303030303b303030303030303030303030303032303b636f6d2e6170706c652e6170702d73616e64626f782e726561642d77726974653b30303030303030313b30313030303030323b303030303030303030326461363838663b2f75736572732f74796c65722f6465736b746f702f74657374666f6c646572

这是我想知道追加是否是问题的另一个原因。

在我的测试中,我让用户选择文件夹,创建安全范围的书签,然后将其保存在用户默认值中。

然后我退出&重新启动应用程序,通过菜单命令,我得到该书签,然后解决它。然后我添加了一个案例,我将已解析的书签用于文件夹,并在文件夹中为该文件创建一个新书签。

似乎工作正常。


在我的测试工作中,我正在获取文件的路径:

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.

如果这不能让你走上正轨,我将需要看到更多代码(你可能需要做一个简单的例子)。

请注意,在我的情况下,我正在解析书签并调用startAccessingSecurityScopedResource,即使我刚收到网址&创建了书签(当我尝试从刚刚从PowerBox(openPanel)获取的路径创建书签时,它失败并出现错误256)。

一些配置细节:OS X 10.8.4,Xcode 5(从今天9/18/2013开始的首次公开发布)。

答案 1 :(得分:4)

要为锁定文件创建书签,请在API调用中使用 NSURLBookmarkCreationSecurityScopeAllowOnlyReadAccess 标记并结合 NSURLBookmarkCreationWithSecurityScope 标记来创建书签。

例如:

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

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

我在Mac OS 10.9.5中试过这个

答案 2 :(得分:2)

在报告安全范围书签和锁定文件的问题后跟进,这是Apple的回复:

“另外,正如您所注意到的,创建一个安全范围的书签需要对目标文件的写访问权限。在OS X Mavericks中不应再这样了。”

这表明它是OS X 10.9之前的版本中的错误。