只需一个函数调用,即可利用 SMJobBless 功能。

let message = "Example App needs your permission to do thingamajig."
let icon = Bundle.main.url(forResource: "bless", withExtension: "png")
try PrivilegedHelperManager.shared.authorizeAndBless(message: message, icon: icon)

messageicon 参数都是可选的。 如果未指定,macOS 将提供默认值。

在 macOS 10.15 及更高版本中,此功能也可作为 async 变体使用,在等待用户授予(或拒绝)授权时不会阻塞。

错误

使用 SMJobBless 最具挑战性的方面之一是,当它失败时,可能很难确定原因。 为了帮助您调试这种情况,此包会抛出一个 BlessError,其中提供了对每个未满足的 bless 要求的详细说明。 例如:

[BlessError] This application did not meet any of the bundled helper tool's code signing requirements:
and {false}
|--and {false}
|  |--and {false}
|  |  |--identifier "com.example.SwiftClient" {false}¹
|  |  \--anchor apple generic {true}
|  \--certificate leaf[subject.CN] = "Apple Development: Johnny Appleseed (U33GZ847WW)" {false}²
\--certificate 1[field.1.2.840.113635.100.6.2.1] {true}

Constraints not satisfied:
1. Identifiers did not match. Expected: com.example.SwiftClient Actual: com.example.SwiftJobBlessClient
2. Apple Development: Tim Apple (U33ZG847WW) is not equal to expected value Apple Development: Johnny Appleseed (U33GZ847WW)

Underlying error: Error Domain=CFErrorDomainLaunchd Code=4 "(null)"

要查看使用此框架的可运行示例应用程序,请查看 SwiftAuthorizationSample,它还使用 SecureXPC 进行安全进程间通信。

macOS 13 及更高版本

如果您的最低部署目标是 macOS 13 或更高版本,Apple 建议您改用 SMAppService 来注册启动守护进程 (Launch Daemon)。

高级用例

如果您需要分别获取授权然后进行 bless,您需要直接使用 Authorized 包(它是 Blessed 的依赖项之一)来创建一个 Authorization 实例,然后将其传递给 PrivilegedHelperManager/bless(label:authorization:) 函数。

沙盒

由于权限提升,沙盒进程无法进行 Blessing。 如果您需要在运行时确定您的进程是否已沙盒化,此包会向 ProcessInfo 添加一个属性:ProcessInfo.processInfo.isSandboxed