【发布时间】:2011-11-26 16:53:27
【问题描述】:
我正在为 Mac OS X 10.7 开发一个沙盒应用程序,我正在尝试以类似于 NSDocument 的方式实现文件保存:
- 将文件的新内容重写为临时文件
- 用临时文件覆盖原始文件
我遇到的问题是沙盒拒绝第 2 步。我在控制台中看到以下行:
sandboxd: XXXX deny file-write-create /Volumes/Home/sbooth/Test Files/Test
我已经打开此文件进行读写,并且我启用了文件系统读/写访问权限。我知道 NSDocument 这样做没有特殊权利,所以我试图找出我错过了什么。
这是我现在的工作方式(应用程序的这一部分是 C++,而不是 Objective-C/C++):
FSRef tempFileFSRef;
if(noErr != FSPathMakeRef((const UInt8 *)tempFileName, &tempFileFSRef, NULL))
; // Handle it
CFURLRef destinationDirURL = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, mURL);
FSRef destinationDirFSRef;
if(!CFURLGetFSRef(destinationDirURL, &destinationDirFSRef))
; // Handle it
CFRelease(destinationDirURL), destinationDirURL = NULL;
CFStringRef destinationName = CFURLCopyLastPathComponent(mURL);
FSRef target;
OSStatus result = FSCopyObjectSync(&tempFileFSRef, &destinationDirFSRef, destinationName, &target, kFSFileOperationOverwrite | kFSFileOperationSkipSourcePermissionErrors);
if(noErr != result)
; // Handle it
如果我禁用沙盒,代码可以正常工作。
编辑:Femi 要求提供更多信息。我使用 C stdio 打开文件:
FILE *f = fopen(reinterpret_cast<const char *>(buf), "r");
并在创建临时文件之前使用fclose 关闭。
我的权利是:
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.assets.music.read-write</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
</dict>
还值得注意的是,Apple 在其App Sandbox Design Guide 中表示:
如果您使用除 NSDocument 类,你必须转换为使用这个类。 NSDocument 类自动与 Powerbox 一起使用。 NSDocument 还提供 如果用户移动,支持将文档保留在沙箱中 他们使用 Finder。
【问题讨论】:
-
除了控制台中的沙盒行,
FSCopyObjectSync是否返回错误? -
它确实返回一个错误:-54 | permErr
-
这也不足为奇,但 FSMoveObjectSync 表现出相同的行为
-
好奇:你能在你打开原始文件的地方包含代码吗?以及您要求的权利?
-
IIRC 沙箱跟踪用户在沙箱中选择的文件...在关闭文件后和打开写入之前再次尝试通过对话框选择文件...跨度>
标签: macos sandbox appstore-sandbox