macOS 开发 -- URL 访问权限持久化(基于 Sandbox)
好久不见,最近有在好好学习哈哈,
今天来分享下基于 Sandbox 的 URL 访问权限持久化的方案。
写这篇文章的起因是:
简单浏览了下 Tencent/lemon-cleaner 的部分源码,
发现他们用 Apple Script 调用 Finder 操作文件,
这样很好地避免了权限问题,但是研究一番发现,没那么简单….
Bookmark 大法
这是我自己项目里使用的方法,
好处在于文件操作很自然, 不会让用户觉得自己的数据可以被随便乱翻(事实也确实是这样的)
将 App Sandbox –> File Access 内的
User Selected File
改为Read/Write
在项目的 entitlements 文件中添加这样一项
com.apple.security.files.bookmarks.app-scope
,设为YES
使用 NSOpenPannel / NSSavePannel 选择需要访问的文件(夹)
在 SwiftUI 中直接用 .fileImporter 之类的 modifer 就行
这样就拿到了用户选择的 URL 啦,因为是用户选择的,目前这个 URL 是有权访问的
注意,是目前,重启 app 就不行了
因此我们需要把权限持久化。
- 保存 URL 的 bookmark
1 | "bookmark") private var bookmark: Data? ( |
1 | do { |
- (app 重启后)再次访问此 URL
1 | guard let bookmark else { return } |
start 和 stop 一定要成对!!
这里属于是访问系统敏感数据,如果不及时 stop 的话系统可能会对 app 的权限做限制,
因此不能滥用,这就是 Sandbox 为什么安全、让人放心的原因了。
url.startAccessingSecurityScopedResource()
也会返回一个布尔值,告诉你你是否真的可以这里的数据了,如果为true
才能算成功。
Apple Script 大法
Apple Script 实际上是代替用户操作的一种脚本,本质上是代替了手动的操作而已,因此这里可以操作所有文件了,在沙盒环境下当然是不会默认允许的。
如果启用了 Hardened Runtime,要先在里面启用 Apple Events,否则无法弹出请求框。
非 Sandbox
如果在 非 Sandbox 环境下,只需要配置 Privacy - AppleEvents Sending Usage Description
告诉用户你执行的脚本的功能是干啥的就行。
然后就可以任意调用 applications了,例如,调用 Finder 来 move 文件之类的。
别慌!即使是非 Sandbox 也会有一步“自动化”授权的!
Sandbox
在 Sandbox 环境下就会有限制了,不会让你能直接访问所有的 applications ,因为这可能会有潜在的恶意行为。
你还是得配置
Privacy - AppleEvents Sending Usage Description
告诉用户你执行的脚本的功能是干啥的,你在需要使用对应的 applications 之前需要去 entitlements 里提前声明。(用到几个写几个)
1 | <key>com.apple.security.temporary-exception.apple-events</key> |
这样你就可以在 app 中使用 NSAppleScript 执行脚本了。
否则,会报错 -600
因为是模拟用户操作的脚本,因此在移动文件、删除文件的时候都会有系统提示音哦~
结尾
目前我的项目中还是使用了 Bookmark 大法,更加简单,不会让用户觉得危险。
主要是 Apple Script 那些弹窗就蛮吓人了…
macOS 开发 -- URL 访问权限持久化(基于 Sandbox)