在启用/不启用沙盒的情况下复制Cocoa App中的文件

时间:2014-01-02 01:25:47

标签: objective-c macos cocoa

第一期:没有沙盒

我遇到了一些复制文件代码的问题。沙盒完全关闭,这个代码。

- (IBAction)installWidget:(id)sender 
{
    // copy widgets to users library
    NSError* error = nil;

    NSString *testUrl = @"~/Library/Widgets/test.wdgt";
    if ([[NSFileManager defaultManager]fileExistsAtPath:testUrl]) {
        NSLog(@"yes");
    }
    NSString *testUrl2 = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: @"test.wdgt"];
    if ([[NSFileManager defaultManager]fileExistsAtPath:testUrl2]) {
        NSLog(@"yes");
    }

    [[NSFileManager defaultManager] removeItemAtPath:testUrl error:nil];
    [[NSFileManager defaultManager]copyItemAtPath:testUrl2 toPath:testUrl error:&error];

    if (error != nil) {
        NSLog(@"%@", [error localizedDescription]);
    }
}

关闭沙盒后,我收到以下错误消息。

文件“test.wdgt”不存在。我尝试使用它来认为将test.wdgt中的代码更改为test.zip时出现平面文件问题我得到了同样的错误。该文件包含在资源包中,但不允许我复制它。

我尝试从构建文件夹外部移动应用程序,同样的问题。我也试过清理build文件夹同样的问题。

第二期:使用沙盒

启用沙盒时出现以下错误。您无权访问目录小部件。

权利文件如下所示

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.assets.movies.read-write</key>
<true/>
<key>com.apple.security.assets.music.read-write</key>
<true/>
<key>com.apple.security.assets.pictures.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/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.print</key>
<true/>
<key>com.apple.security.temporary-exception.files.absolute-path.read-write</key>
<array>
    <string>/Users/jon/Library/Widgets/</string>
</array>
</dict>
</plist>

我正在靠墙打我的头。我尝试添加一个简单的图像,然后用窗口小部件名称替换图像名称,只要禁用沙盒,它就会复制得很好。我编写了一个可以与我的应用程序一起使用的小部件,我想通过允许用户通过单击应用程序中的按钮或菜单项来安装小部件来分发它。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

在非沙箱问题上,您需要展开波形符(~),然后才能在文件系统操作的路径中使用它。一种方法是在您创建的字符串上调用-stringByExpandingTildeInPath,但获取此类文件夹的最佳做法是使用:

NSArray *paths = NSSearchPathForDirectoriesInDomains
                           ( NSLibraryDirectory, NSUserDomainMask, YES);

这将返回一个数组(应该只是1个元素),其中包含用户库目录路径的字符串。然后,您可以使用-stringByAppendingPathComponent:

将特定路径元素添加到该元素中

因此,你可以通过以下方式获得完整的路径:

NSString *widgetsPath = [[paths objectAtIndex: 0] stringByAppendingPathComponent:
                             @"Widgets"];

至于在沙箱中进行操作,您当前的代码将因错误的目录而失败,该目录将无法访问(因为~被解释为路径组件而不是替换用户的主目录) 。但是,您显然无法通过枚举每个用户来在运输代码中使用绝对路径异常。如果您打算使用沙盒,您可能需要找到另一种安装方法。您可以只打开窗口小部件文件,从而让操作系统为您复制它。否则,您将不得不以某种方式询问用户的权限,例如弹出一个打开的窗口并将路径传递给用户的Widget文件夹。