拖动文件遇到沙箱(__ CFPasteboardIssueSandboxExtensionForPath)

时间:2012-08-09 10:54:28

标签: objective-c macos cocoa sandbox nspasteboard

我处理了从浏览器视图到自定义视图的拖动操作。它在雪地上工作得很好,但在带有沙箱的Mountain Lion中却没有。

in browser view:
    NSMutableArray* urls = [[[NSMutableArray alloc] init] autorelease];
..............put some NSUrl to urls array....................
    [pasteboard writeObjects:[NSArray arrayWithArray:urls]];

in my receive custom view:
    NSArray* pasteboardItems = [pasteboard readObjectsForClasses:[NSArray arrayWithObject:[NSString class]] options:nil];
    NSArray* pasteboardItems2 = [pasteboard readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] options:nil];
    NSArray* pasteboardItems3 = [pasteboard readObjectsForClasses:[NSArray arrayWithObject:[NSImage class]] options:nil];
    NSLog(@"%@",pasteboardItems);
    NSLog(@"%@",pasteboardItems2);
    NSLog(@"%@",pasteboardItems3);
my log is:
    2012-08-09 18:33:43.886 iCollage[6885:303] __CFPasteboardIssueSandboxExtensionForPath: error for [/Users/xxxx/Library/Containers/xxxxxxxxxxxx/Data/Downloads/1343902069.jpg]
    2012-08-09 18:33:44.546 iCollage[6885:303] ( "file://localhost/Users/xxx/Library/Containers/xxxxxxxx/Data/Downloads/1343902069.jpg")
    2012-08-09 18:33:44.547 iCollage[6885:303] ( "file://localhost/Users/xxxxx/Library/Containers/xxxxxx/Data/Downloads/1343902069.jpg")
    2012-08-09 18:33:44.547 iCollage[6885:303] ()

我的问题是:

1.如何修复此错误__CFPasteboardIssueSandboxExtensionForPath;我引用文档并发现没有任何关于那个。我有权获得访问该文件的权限!google说,可能是“startAccessingSecurityScopedResource”会帮助我,然后我尝试

2.为什么pasteboardItems2有价值?我只写了粘贴板而不是字符串。我很反感我可以从NSString类型和NSUrl类型获取url! (我尝试从iFinder拖动文件,网址只存在于pasteboardItems中但不存在于pasteboardItems2中。)有人知道为什么吗?我认为当有人帮助我解决这个问题时,第一个问题会自动解决。

4 个答案:

答案 0 :(得分:1)

我相信Apple回答问题1:

  

重要:虽然您可以支持拖动文件路径,但一般来说,   除非你确定目的地,否则你应该避免这样做   应用程序将永远不会在应用程序沙箱中运行。如果您使用NSString,OS X.   无法知道该字符串是否应该被解释为a   路径;因此,OS X不会将目标应用程序的沙箱扩展为   允许访问该位置的文件或目录。相反,使用   NSURL,书签或文件名粘贴板类型。

WRT问题2,看起来您已粘贴了网址,因此阅读NSURL个对象似乎是正确的。但是我认为你应该使用以下代码实现拖动(也来自上面的链接):

- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
    NSPasteboard *pboard = [sender draggingPasteboard];

    if ( [[pboard types] containsObject:NSFilenamesPboardType] ) {
        NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
        int numberOfFiles = [files count];
        // Perform operation using the list of files
    }
    return YES;
}

答案 1 :(得分:1)

发送方需要generate security-scoped URL bookmark data,接收方需要turn that data back into a URL。当你想要实际访问URL时,你还需要做一些其他的事情; the documentation elaborates

接收应用程序在沙箱中运行时,将无法处理裸路径。这是沙盒的核心部分;您不得使用裸路径或其相应的URL来访问不在沙盒容器中且未由用户明确传递给您的文件。

答案 2 :(得分:0)

您的 pasteboardItems 读取NSString类型的对象,但是您拖动了一个文件(扩展名为jpg),您应该在init方法中注册NSString类型:

[self registerForDraggedTypes:[NSArray arrayWithObject:NSPasteboardTypeString]];

答案 3 :(得分:0)

您需要在应用程序中定义文档类型,以便沙盒机制知道您的应用程序应该打开具有这些扩展名的文件。您可以通过单击Xco​​de左侧的项目来完成此操作,并在“信息”选项卡的“文档类型”下为每个扩展名添加新的文档类型。

您只需填写nameextensions字段。

此外,如果您希望保留访问拖动到应用程序中的文件的权限,则可以使用此类来包含所有逻辑。 https://github.com/leighmcculloch/AppSandboxFileAccess