MacOS 开发 — 最近打开文件(Security-scoped bookmark)

周超英
2023-12-01

问题:

Mac OS X APP在开发完成,上线的时候必须支持sandbox[https://blog.csdn.net/heroguo_jp/article/details/54862223] 当设置完成SandBox之后 发现,打开最近文件.txt 之后修改保存,当再次打开的时候发现不能 打开运行啦?

原因:

Mac OS X系统为了保证系统的安全性采取啦安全保护机制。不允许你在没有文件流的的方式打开文件【没有权限打开】。

解决方案:
Security-scoped bookmark

在File Access中 User Selected File项中选择Read/Write 文件的读写权限 ,沙盒有一个默认的规则: 在APP 运行期间通过NSOpenPanel打开的任意位置的文件,把这个路径保存下载,后面都可以直接使用这个路径继续访问文件获取文件的读写权限。

但是在APP重新启动以后,这个文件路径不能直接被访问,要想要永久的访问APP之外的路径,就必须使用Security-scoped bookmark

Security-scoped bookmarks有2种:

An app-scoped bookmark:可以对应用中打开的文件或者文件夹在以后永久性访问儿不需要再次通过NSOpenPanel打开。这种bookmark方式使用的比较多。

A document-scoped bookmark: 提供对特定的文档的永久访问权。可以理解针对文档嵌套的一种权利模式。比如你开发一个能编辑ppt文档的应用,里面嵌入了视频文件,图片文件连接。那么下次打开这个ppt文档时就能直接访问这些文件而不需要在通过NSOpenPanel打开获得授权。

方法:

1、 保存打开文件的URL的Bookmark
获取URL中的bookmarkData存储到NSUserDefaults中

 NSData *bookmarkData = [fileURL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
                         includingResourceValuesForKeys:nil
                                          relativeToURL:nil
                                                  error:&error];

2、应用启动时通过URL的bookmark获取文件授权
通过bookmark数据解析获取授权的NSURL,并且执行startAccessingSecurityScopedResource方法得到访问权限。
执行block回调完成相关内容读取后,执行stopAccessingSecurityScopedResource停止授权。

  NSURL *allowedUrl = [NSURL URLByResolvingBookmarkData:bookmarkData
                                                      options:NSURLBookmarkResolutionWithSecurityScope
                                                relativeToURL:nil
                                          bookmarkDataIsStale:&isStale
                                                        error:NULL];

@try {
[allowedUrl startAccessingSecurityScopedResource];
block();
} @finally {
[allowedUrl stopAccessingSecurityScopedResource];
}

Demo 地址:https://github.com/heroBlog/HGBookmark.git

 类似资料: