OS X沙箱中的非就地保存

时间:2011-11-26 16:53:27

标签: macos sandbox appstore-sandbox

我正在为Mac OS X 10.7开发一个沙盒应用程序,我正在尝试以类似于NSDocument的方式实现文件保存:

  1. 将文件的新内容重写为临时文件
  2. 使用临时文件
  3. 覆盖原始文件

    我遇到的问题是沙箱拒绝了第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   class自动与Powerbox一起使用。 NSDocument还提供   支持在用户移动时将文档保留在沙箱中   他们使用Finder。

1 个答案:

答案 0 :(得分:0)

沙箱只允许您从应用程序的容器中读取和写入。如果启用了读/写权限,则只能访问通过OpenSavePanel打开的文件(或某些方法,例如将图标拖到用户专门打开文件的停靠栏中)。这将严重限制应用程序如何处理文件系统上的文件。

因此,只要您的应用程序具有写入相关文档的权限,您就可以将临时文件写入应用程序容器,然后检索临时文件内容,然后保存到原始位置。但是,这假定您的应用程序在整个过程中维护对原始文件的权限。

所以,我的建议是确保你所做的任何写作都在应用程序容器中完成,然后在调用保存函数之前验证你的应用程序是否仍有权写入真实文件位置。

我最近写了一个类似的问题,我的应用程序无法访问已打开的文件,因为另一个(非沙盒)应用程序已保存到同一文件中。然后,沙盒会让该应用访问我的文档并从应用中删除权限。