我正在编写一个可以运行沙盒的应用程序。
我喜欢保持我的代码独立于我是否稍后将其编码为沙盒,即我希望在我的代码(或构建环境)中有一个常量,我必须更改代码以了解是否它是否会为沙箱而建。
当然,我需要在我的代码中使用不同的API,具体取决于应用程序是否为沙盒。
所以,我喜欢在我的应用程序中使用代码来动态检测它是否在沙盒中运行。我喜欢这样做而不在控制台日志中收到消息。即,尝试访问沙盒中无法访问的文件不是一个好的解决方案,因为这会导致日志条目反过来会激怒我的应用程序的用户,认为有些问题。
答案 0 :(得分:1)
正如您所提到的,沙盒化的应用程序是代码签名的。您可以通过对'codesign'的命令行调用来检查是否存在此问题。
因此,如果您的程序可以使用以下命令调用命令行: -
codesign -d --entitlements :- <path to executable>
从命令中检索输出并搜索字符串: -
com.apple.security.app-sandbox
如果字符串存在,则运行的可执行文件将被沙箱化。在应用程序启动时的初始化函数中执行此操作一次,并存储一个标记,然后可以测试该标记。
------- EDITED ----------------
我自己没有对它进行过测试,但只是遇到了this article,其中包含检查应用是否为沙盒的代码。完整代码可以在github上找到here。
----编辑2 --------------
我终于检查了aforementioned article中的代码,并确认它按预期工作。
答案 1 :(得分:1)
我现在发现了一个更简单的技巧:
我获得了Preferences文件夹的路径。如果它看起来像这样,我就是沙箱:
/Users/<user>/Library/Containers/<bundle_id>/Data/Library/Preferences
这足以满足我的需求,我只是想避免看到控制台消息。如果Apple改变了路径并且我的测试失败了,那么我将看到的最糟糕的是一个关于拒绝操作的控制台消息。我可以忍受。
答案 2 :(得分:1)
import Foundation // For String/CFString bridging
import Security
if
let task = SecTaskCreateFromSelf(nil),
let value = SecTaskCopyValueForEntitlement(task, "com.apple.security.app-sandbox" as CFString, nil),
let isSandboxed = value as? Bool
{
print("sandbox: \(isSandboxed)")
}
答案 3 :(得分:0)
我用这个:
// Determine if an application is running in sandboxed mode
func IsSandboxed() -> Bool {
let dir = NSHomeDirectory()
let bundleName: String = NSBundle.mainBundle().bundleIdentifier as String!
if dir.containsString("Library/Containers/" + bundleName) {
return true
}
return false
}