OS X App 沙盒和任意文件访问 - 更新到基于文档?

OS X App Sandboxing and arbitrary files access - Update to Document-based?

我的 OS X 应用程序(当前未沙盒化)访问包含在用户设置的目录中的文件(选择带有 NSOpenPanel 的路径并且在整个执行过程中保留对此路径的引用).文件列表是通过 NSDirectoryEnumerator 生成的,然后我分别使用 AVAssettaglib(在带有桥接头的 C++ 中)读取和写入这些文件。

正如预期的那样,在 Xcode 中启用沙盒使应用程序无用,NSDirectoryEnumerator 给出的文件列表是空的,即使不是,我也无法读取并写入文件。我需要采取哪些步骤才能使我的应用符合沙盒标准?

我的应用程序是否需要基于文档?我的应用程序真的可以 "document-based" 吗,因为我没有真正的文档(如:我没有每个文件的 window,它似乎不符合基于文档的标准应用模型)?我的应用程序基本上只是一个 table 视图,其中文件引用作为行。 另一个要点:如果我的应用程序是基于文档的,我还能使用 taglib 来写入我的文件吗?我需要将文件路径作为字符串指针传递给 taglib 才能使其正常工作。

非常感谢,这个话题目前比较混乱。

听起来当前功能可以很好地转换为沙盒。

  1. 用户通过 NSOpenPanel 选择目录(这将在沙盒环境中调用名为 Powerbox 的东西)。
  2. 此目录现在可写,因为用户已明确选择它。
  3. 您甚至可以通过创建安全范围书签并将其存储在会话之间来保持对此目录的写入权限。

这与基于文档毫无关系;这是一个与沙盒无关的内部设计。

您无需将应用程序转换为基于文档的应用程序即可访问用户选择的文件和安全范围内的书签。

我能想到您当前的代码无法在沙盒环境中运行的两个原因:

  • 您没有 "User Selected File Access" 功能集(Xcode > 目标 > 功能 > 应用沙盒 > 文件访问)
  • 您正在使用基于 path/NSString 的 API 目录枚举器,而不是基于 URL NSURL 的目录枚举器。

启用沙盒和用户选择的文件功能集的原始 Xcode 项目,应枚举通过 NSOpenPanel:

获得的任何路径
NSOpenPanel* panel =[NSOpenPanel openPanel];
panel.canChooseDirectories = YES;
[panel beginSheetModalForWindow:self.view.window completionHandler:^(NSInteger result) {
    NSFileManager *fileManager = [[NSFileManager alloc] init];
    NSURL *directoryURL = panel.URL;
    NSDirectoryEnumerator *enumerator = [fileManager
                                         enumeratorAtURL:directoryURL
                                         includingPropertiesForKeys:nil
                                         options:0
                                         errorHandler:nil];
    for (NSURL *url in enumerator) { 
        NSLog(@"url:%@", url);
    }
}];

如果您想存储跨应用程序 launch/quit 周期从沙箱访问特定文件夹的能力,您将需要存储一个安全范围的书签。 此 post 包含持久用户选择 file/directory 通过应用范围书签访问的信息: Trouble creating Security-Scoped Bookmark