如何在开启App Sandbox的Cocoa应用内关闭Preview进程?
在App Sandbox环境下关闭Preview的解决方案
问题原因
App Sandbox的隔离机制默认禁止应用直接终止其他进程,terminate()和kill()这类操作会因权限不足失效。要操控其他应用,需通过Apple Events并配置相应的权限例外。
解决步骤
1. 添加Apple Events权限例外
在项目的Entitlements.plist文件中,添加针对Preview的Apple Events临时例外权限:
<key>com.apple.security.temporary-exception.apple-events</key> <array> <string>com.apple.Preview</string> </array>
该配置允许你的应用向Preview发送Apple Events请求。
2. 修改关闭逻辑为Apple Events调用
替换原有的closeApp()方法,通过Apple Script发送关闭请求,这是沙箱环境下控制其他应用的标准方式:
func closeApp() { // 使用Apple Script请求Preview退出 let quitScript = NSAppleScript(source: """ tell application "Preview" quit end tell """) // 执行脚本(可根据需求添加错误处理逻辑) _ = quitScript?.executeAndReturnError(nil) }
3. 优化应用实例获取(可选)
原openApp()方法通过runningApplications查找Preview可能匹配到已运行的其他实例,建议改为通过open(_:options:configuration:completionHandler:)获取打开当前PDF的具体实例:
func openApp(at url: URL) { let configuration = NSWorkspace.OpenConfiguration() configuration.activates = true NSWorkspace.shared.open([url], configuration: configuration) { (apps, error) in // 获取打开该PDF的Preview实例 self.pdfApp = apps?.first(where: { $0.bundleIdentifier == "com.apple.Preview" }) } }
注意事项
- 首次运行时,系统会弹出授权对话框,需用户允许你的应用控制Preview,授权后后续操作无需重复确认。
- Apple Events方式比直接终止进程更符合系统安全规范,还能保证Preview正常保存未完成的操作。
内容的提问来源于stack exchange,提问作者Haxad
相关产品推荐
相关产品推荐

