从6月1日开始,Apple要求所有提交到App Store的应用程序都必须运行在沙盒环境中,这可苦了我们这些悲催的码农。一则受到沙盒环境的种种限制,一些很常用的操作都没法实现;二则App Sandbox本身就是BUG重重,这个更是有理没处说。
举个例子,常规环境中,一般使用Shared File List API来设置程序随系统自动运行。到了沙盒环境中,Apple不许我们使用此API了,而建议使用Service Management来实现类似功能。Service Management不如传统方法直接,必须将一个Helper程序设置为启动项,由Helper程序唤起主程序,而且创建的启动项不能显示在系统设置中。这就算了,问题是Helper程序怎么也不能唤起主程序,这个BUG直到10.7.4才解决。
言归正传,本文要说的是另一个BUG。通常,如果需要展示某个文件夹的内容,我们会使用NSWorkspace的OpenURL方法。即使在沙盒环境中,只要已经取得了该文件夹的相关权限,此方法显然也应该没问题。但Apple不这么想,直到目前的Lion 10.7.4中,即便是打开沙盒容器中的目录都无法成功,可以在控制台看见这样的信息。
CoreServicesUIAgent: Quarantine resolution refused to pid 5872 because it is not allowed to read /Users/xxxx/Library/Containers/com.xxxxx.xxxxx/Data/Library/Application Support
这显然是一个BUG,而且实际上程序是可以对沙盒目录进行读写的,不可能真的没有权限。
于是上网寻求解决方案,最终在The Unarchiver的代码中找到了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
看看函数名称,看来抱怨App Sandbox的人不仅仅只是我。:)
使用这个方法,必须在App Sandbox的授权文件中为Finder增加特例。
1 2 |
|
至于这样能否通过App Store的审核,要看审核人员的心情了,至少The Unarchiver是通过了,我的App还在等待审核,前途未卜。说到这个,小小发下牢骚,为了实现将文件解压到压缩包所在的目录,The Unarchiver在授权文件中加了一堆目录的读写权限;而我为了实现类似的功能(从PDF文件中提取图片)使用了相同的方法,死活不能通过审核!
补充:又一次被拒了,就是因为这个Finder的例外。苹果的双重标准太恶心了,而且还在文档中明确指出不能以别的App通过审核作为申诉的理由,去TNND。
再补充:
- 发现一个奇怪的现象,若沙盒下的子目录是由程序创建的,无法使用NSWorkspace的openURL或openFile方法打开;若子目录通过Finder或命令行手工创建,则上述BUG不存在。比较过两种方法创建的目录,所属用户、组、权限都一样,百思不得其解。
- NSWorkspace的selectFile:inFileViewerRootedAtPath:方法可以正常工作。