沙箱Mac应用程序耗尽安全范围的URL资源 [英] Sandboxed Mac app exhausting security scoped URL resources

查看:347
本文介绍了沙箱Mac应用程序耗尽安全范围的URL资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Mac应用程序,提示用户使用NSOpenPanel的文件。应用程序是沙盒(在OSX 10.9.4上测试)。我注意到,如果我打开大量的文件(〜3000),打开面板开始发出错误日志。这也发生,如果我试图打开少量的文件在卡盘几次。



第一次出现错误后,每当NSOpenPanel再次用于打开文件时,无论多少文件,这些错误都会再次生成




$ b

错误消息如下所示:

$ c> TestPanel [98508:303] __41 + [NSSavePanel _consumeSandboxExtensions:] _ block_invoke:sandbox_consume_fs_extension failed



我设法使用一个简单的应用程序来重现这个行为:一个沙箱应用程序使用单个按钮调用以下代码:

  NSOpenPanel * panel = [NSOpenPanel openPanel]; 
[panel setAllowsMultipleSelection:YES];
[panel setCanChooseDirectories:NO];
[panel setCanChooseFiles:YES];
[panel beginSheetModalForWindow:[self window] completionHandler:^(NSInteger result){
NSLog(@%lu,[panel.URLs count]);
}];

错误出现在代码到达完成处理程序之前。



似乎我仍然可以从完成处理程序的面板中获取URL,但它真的污染了系统日志。



编辑: / strong>



似乎这个问题与NSOpenPanel / NSSavePanel面板没有直接关系。当使用drap / drop与文件时,会发生非常类似的事情。像这样:

   - (NSDragOperation)draggingEntered:(id< NSDraggingInfo>)sender {
...
NSPasteboard * pboard = [sender draggingPasteboard];
if([[pboard types] containsObject:NSURLPboardType]){
NSArray * urls = [pboard readObjectsForClasses:@ [[NSURL class]] options:nil];
}
...
}

拖动大量文件(魔术数字似乎在2900左右)时出现以下日志消息:

 项目标识符(2937)从粘贴板的扩展失败! 

与NSOpenPanel一样,在第一次出现之后,每个文件丢弃都会产生相同的错误



@mahal tertin的回复指向我向正确的方向。问题确实是文件数量和安全范围的URL资源有限的事实。



但是,似乎没有找到合理的解决方案。问题是,当用户在NSOpenPanel上点击确定(或删除拖放感知控件上的文件)时,操作系统已经尝试创建这些安全范围的URL并隐式调用 startAccessingSecurityScopedResource 。因此,如果用户尝试打开的文件超过限制,则资源将耗尽,唯一的选择是关闭并重新启动应用程序。



调用 stopAccessingSecurityScopedResource 似乎可以释放资源,但是这个解决方案对于官方开发者论坛(链接后面的登录)。



似乎应用程序是用户不打开太多的文件。这甚至不是一次,因为没有批准的方式来发布这些资源。您可以在文档中或甚至在应用内警告中警告用户,但没有办法阻止他们搞砸应用并强制重新启动。



因此,如果应用运行时间足够长,用户保持打开文件,应用最终将无法使用。



仍在寻找合理的解决方案。

解决方案

搜索高低之后,各种地方,我要关闭这个问题,并得出结论,没有答案或解决方案。我发布了已知的信息,供将来参考。



所有建议的解决方案只是解决方法,可以最大限度地减少问题,并试图指导用户不试图打开文件太多。但是没有什么可以做到真正解决这个问题。



以下是有关此问题的已知事实:




  • do,用户可以尝试在NSOpenPanel对话框中打开过多的文件,并耗尽安全范围的URL资源

  • 一旦这些资源耗尽,就无法再打开任何文件/写作。应用程序需要关闭并重新打开。

  • 即使用户未尝试一次打开太多文件,如果应用程序运行时间足够长,也可能会耗尽这些资源,而用户随着时间的推移打开足够的文件,因为对使用NSOpenPanel打开的文件(或拖放机制)会自动调用 startAccessingSecurityScopedResource ,并且没有任何东西关闭这些资源

  • 在开放面板检索到的所有网址上调用 stopAccessingSecurityScopedResource 将释放这些资源,但Apple不鼓励这种做法,称其可能与以后的解决方案不兼容

  • 当您收到来自NSOpenPanel(或拖放)的URL列表时,无法确定是否成功访问所有URL,或者是否存在超过限制的URL,因此无效。

  • Apple知道这一点,并可能在将来修复它。它仍然不是固定的10.10,当然,这将不会帮助当前/以前OSX版本上运行的当前应用程序。



苹果真的放弃了这个球,沙盒的实现似乎非常马虎和短视。


I am developing a Mac application that prompts the user for files using the NSOpenPanel. The application is sandboxed (testing on OSX 10.9.4). I noticed that if I open a large amount of files (~3000), the open panel starts to emit errors to the log. This also happens if I try to open less amount of files in chucks for several times.

After the errors start to appear the first time, every time the NSOpenPanel is used again to open files, no matter for how many files, these errors will be generated again (until the application is closed).

The error message looks like this:

TestPanel[98508:303] __41+[NSSavePanel _consumeSandboxExtensions:]_block_invoke: sandbox_consume_fs_extension failed

One line for each file I try to open.

I managed to reproduce this behavior with a simple app: A sandboxed application with a single button invoking the following code:

NSOpenPanel* panel = [NSOpenPanel openPanel];
[panel setAllowsMultipleSelection:YES];
[panel setCanChooseDirectories:NO];
[panel setCanChooseFiles:YES];
[panel beginSheetModalForWindow:[self window] completionHandler:^(NSInteger result) {
    NSLog(@"%lu", [panel.URLs count]);
}];

The errors appear before the code reaches the completion handler.

It seems that I can still get the URLs from the panel in the completion handler but it really pollutes the system log.

EDIT:

Seems that this problem is not directly related to the NSOpenPanel/NSSavePanel panels. A very similar thing happens when using drap/drop with files. Something like this:

- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender {
    ...
    NSPasteboard *pboard = [sender draggingPasteboard];
    if ([[pboard types] containsObject:NSURLPboardType]) {
        NSArray *urls = [pboard readObjectsForClasses:@[[NSURL class]] options:nil];
    }
    ...
}

This will generate the following log messages when dragging a large amount of files (the "magic" number seems to be somewhere around 2900):

Consume sandbox extension for itemIdentifier (2937) from pasteboard failed!

As with the NSOpenPanel, after the first occurrence of this, every single file dropped will generate the same error in the log.

EDIT 2:

@mahal tertin's reply pointed me to the right direction. The problem is indeed with the number of files and the fact that security scoped URL resources are limited.

However, there seems to be no reasonable solution found. The problem is that when the user clicks "OK" on the NSOpenPanel (or drops the files on a drag&drop aware control), behind the scenes the OS already attempts to create these security scoped URLs and implicitly calls startAccessingSecurityScopedResource for you. So if the user attempts to open more files than the limit, the resources are exhausted and the only option is to close and restart the application.

Calling stopAccessingSecurityScopedResource on the returned URLs seem to free the resources however this solution was discouraged by Apple's representative on the official developers forums (link is behind login).

It seems that the app is at the mercy of the user not to open too many files. And that is not even at once, since there is no approved way to release these resources. You can warn the user in documentation or even with an in-app alert but there is no way to prevent them from messing up the app and forcing a restart.

So if the app runs long enough and the user keeps opening files, the app will eventually become unusable.

Still looking for a reasonable solution for this.

解决方案

After searching high and low and asking in various places, I am going to close this question and conclude there is no answer or solution to this. I am posting the known information on this for future reference.

All the solutions suggested are just workarounds that may minimize the problem and try to guide the user toward not trying to open too many files. But there nothing that can be done to actually solve this.

Here are the known facts about this issue:

  • No matter what you do, the user can attempt to open too many files in the NSOpenPanel dialog and exhaust the security scoped URL resources
  • Once these resources are exhausted, it is not possible to open any more files for reading/writing. The application needs to be closed and reopened
  • Even if the user doesn't attempt to open too many files at once, the application may still exhaust these resources if it runs long enough and the user opens enough files over time since startAccessingSecurityScopedResource is called automatically for files opened with NSOpenPanel (or the drag/drop mechanism) and nothing ever closes these resources
  • Calling stopAccessingSecurityScopedResource on all URL retrieved by the open panel will free these resources but this practice is discouraged by Apple, saying it might not be compatible with future solutions
  • When you receive the list of URLs from NSOpenPanel (or drag/drop), there is no way to tell if all URLs were successfully accessed or if there are URLs that are over the limit and therefore invalid.
  • Apple is aware of this and may fix it in the future. It is still not fixed in 10.10 and of course, that will not help current applications running on current/previous OSX version.

It seems Apple has really dropped the ball on this one, the Sandbox implementation seems very sloppy and short sighted.

这篇关于沙箱Mac应用程序耗尽安全范围的URL资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆