有没有办法让我的沙盒 Mac 应用程序只读访问 ~/Library 中的文件?
Posted
技术标签:
【中文标题】有没有办法让我的沙盒 Mac 应用程序只读访问 ~/Library 中的文件?【英文标题】:Is there any way to give my sandboxed Mac app read only access to files in ~/Library? 【发布时间】:2012-06-08 15:58:46 【问题描述】:我对沙盒有点困惑。这可能吗?
谢谢!
【问题讨论】:
是否可以使用“com.apple.security.temporary-exception.files.absolute-path.read-write 获得对我的应用程序的写权限”启用对指定文件的读/写访问权限或指定绝对路径的目录。” 为什么有 10 个用户喜欢这个但只有 8 个用户点赞...? 【参考方案1】:是的,但它需要“临时例外”权利。 “临时”意味着它可能会在操作系统的某些未来版本中消失,但这并没有太大的风险。更大的问题是“例外”这个词:这意味着您必须证明您使用该权利的合理性,否则 App Store 审核者可能会拒绝您。
提交一份错误报告,准确解释您认为自己应该能够做什么,但如果不能访问~/Library
,今天就无法做到这一点,理想情况下还可以在该主题上启动一个论坛帖子。他们可能会建议使用一种解决方法,而不是访问~/Library
(甚至可能使用私有 API),在这种情况下,按照他们所说的去做。或者他们可能会说暂时使用临时例外,在这种情况下,这样做。或者他们可能没有响应,在这种情况下,您使用临时例外并交叉手指。在任何情况下,请确保您的 App Store 提交评论注释包含指向错误报告和/或论坛主题的链接。
您必须手动编辑项目的权利 plist 才能做到这一点,但这并不难。创建一个com.apple.security.temporary-exception.files.home-relative-path.read-only
数组,其中包含一个字符串"/Library/"
。像这样:
<key>com.apple.security.temporary-exception.files.home-relative-path.read-only</key>
<array>
<string>/Library/</string>
</array>
末尾的额外/
是沙盒如何知道您要访问目录而不是文件的方式。如果你把它关掉,你将可以访问~/Library
中的所有文件,这是你要求的,但不能访问~/Library
的(递归)子目录中的文件,比如~/Library/LaunchAgents/com.mycompany.myapp.myoldagent.12345678-ABCD-EF00-1234-567890ABCDEF.plist
,这就是你可能想要。请参阅权利密钥参考文档中的File Access Temporary Extensions。
另外,请注意,您已经可以“免费”访问 ~/Library
下的某些内容,因为它们被复制到您的容器中,或者在您使用适当的 API 而不是使用路径时间接访问。因此,可能有更好的方法来完成您正在做的事情——例如,读取您的应用程序以前的非沙盒版本留下的文件,您可能能够将它们迁移到容器中并在那里读取它们。
还有一件事:仅仅访问 ~/Library 并不会改变 NSHomeDirectory()
、URLsForDirectory:inDomains:
等将返回的内容——您仍然会得到 ~/Containers/com.mycompany.myproduct/Data/Library
。 Apple 的半官方建议是使用 BSD API 来获取用户的真实主目录,最简单的方法是:
const char *home = getpwuid(getuid())->pw_dir;
NSString *path = [[NSFileManager defaultManager]
stringWithFileSystemRepresentation:home
length:strlen(home)];
NSURL *url = [NSURL fileURLWithPath:path isDirectory:YES];
几点说明:
过于频繁地拨打getpwuid
通常不是一个好主意。最好的解决方案是提前调用此代码一次,然后缓存生成的NSURL
。
这显然也可用于获取其他用户的主目录(因此也可用于获取 Library
),但 App Store 几乎肯定不会允许任何实际尝试这样做的软件。
库位于~/Library
的事实被认为是一个“实施细节”,可能有一天会改变,这是另一个原因(在权利之上)这必须被视为临时解决方法,直到 Apple 提供真正解决您更高级别问题的方法,并且可能值得在您的评论笔记中提及。
【讨论】:
赞成,尽管您提出的使用getpwent()->pw_dir
的解决方案为我返回/var/virusmails
。
这对我有用:getpwnam([NSUserName() UTF8String])->pw_dir
对不起; “正确”的方式是 getpwuid(getuid()),而不是 getpwent()(返回第一个条目)。由 Apple 的一位沙盒工程师在论坛上认可的原始解决方案有同样的错误,后来被纠正,不知何故错误的版本卡在我的脑海里。我已经更新了我的答案。无论如何,getpwnam 和 getpwuid 一样好,所以你可以坚持那些已经为你工作的东西。
@anka:嗯,他要求“~/Library 中的文件”,但你是对的,他几乎肯定想要~/Library 的某个子目录 下的文件。 以上是关于有没有办法让我的沙盒 Mac 应用程序只读访问 ~/Library 中的文件?的主要内容,如果未能解决你的问题,请参考以下文章
在其他 Mac 上的沙盒中测试 Mac Appstore 的 IAP