startAccessingSecurityScopedResource从不返回成功

7

我正在开发一款沙盒化的Mac App Store应用,它会询问用户从其他地方下载文件时希望将文件保存在哪里。我有以下代码来获取用户选择的文件夹(省略了一些错误检查):

NSOpenPanel* openPanel = [NSOpenPanel openPanel];
[openPanel setAllowsMultipleSelection:NO];
[openPanel setCanChooseDirectories:YES];
[openPanel setResolvesAliases:YES];
NSInteger result = [openPanel runModal];
NSArray* urls = [openPanel URLs];
NSURL* folderURL = [urls objectAtIndex:0];
NSError* error;
NSData* bookmakeData = [folderURL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
                           includingResourceValuesForKeys:nil
                                            relativeToURL:nil
                                                    error:&error];
_saveFolderBookmark = bookmakeData;

当需要将一个文件移动到这个文件夹时,我有如下代码:

BOOL isStale;
NSError* error;
NSURL* saveFolder = [NSURL URLByResolvingBookmarkData:_saveFolderBookmark
                                              options:NSURLBookmarkCreationWithSecurityScope
                                        relativeToURL:nil
                                  bookmarkDataIsStale:&isStale
                                                error:&error];
BOOL success = [saveFolder startAccessingSecurityScopedResource];

// Move the file somewhere else
NSWorkspace* workspace = [NSWorkspace sharedWorkspace];
NSInteger operationTag;
BOOL copied = [workspace performFileOperation:NSWorkspaceMoveOperation
                                       source:[[self getDocumentsFolder] path]
                                  destination:[saveFolder path]
                                        files:[NSArray arrayWithObject:filename]
                                          tag:&operationTag];
[saveFolder stopAccessingSecurityScopedResource];

这是一大段代码,说的是无论是在从NSOpenPanel获取URL后立即调用startAccessingSecurityScopedResource还是在稍后运行时,使用NSUserDefaults保存书签数据,该函数都不会返回成功。

在授权文件中,除了其他项之外,我有:

<key>com.apple.security.files.bookmarks.app-scope</key>
<true/>

这段代码有什么问题吗?


你看到任何控制台消息吗?另外,请仔细检查代码签名,确保其正确配置。 - gaige
在你的例子中,打开面板完成后urls数组的来源不清楚。 - gaige
我成功地编辑掉了获取URL的那一行,当我移除错误检查时。现在我已经把它放回去了。在调用startAccessingSecurityScopedResource的那一行周围没有任何控制台消息。 - Gary Makin
2个回答

9

这很简单。您正在使用NSURLBookmarkCreationWithSecurityScope而不是NSURLBookmarkResolutionWithSecurityScope进行解析。只需更改该行即可。

(如果您已经可以访问URL,则可能无法在创建书签的同一会话中工作,因为在这种情况下不应调用它。但是在以后的运行中,当然应该可以,因为这就是整个目的。)


现在看来非常明显,一旦指出就让人想知道为什么有两个不同的常量。谢谢! - Gary Makin
2
如果你看看历史,这就说得通了。在10.6中,原始的BookmarkCreation和BookmarkResolution标志集没有任何匹配的对,因此它们是完全独立的位掩码值集,并且不会混淆,例如NSURLBookmarkCreationMinimalBookmark和NSURLBookmarkResolutionWithoutUI之间。但是,如果他们添加了一些编译器警告的方式,那就太好了,不是吗? - abarnert

2
上面已经给出了正确的解决方案,但我想为那些遇到相同症状(startAccessingSecurityScopedResource从未返回YES)的人添加另一个可能性。请确保您使用的是Powerbox返回的实际URL,这个URL可能与您尝试访问的实际资源的URL(很可能)不同。例如,Powerbox将返回一个路径的URL,您可以将其与startAccessingSecurityScopedResource一起使用来访问该目录下的特定文件。

今天我被这个问题困扰了。我正在调用startAccessingSecurityScopedResource,使用的是一个在我获取书签的文件夹下面的文件夹。感谢您提供的答案。 - Tap Forms

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接