标签: security-scoped-bookmarks

处理陈旧的NSURL书签的正确方法是什么?

从安全范围书签解析NSURL时,如果用户重命名或移动了该文件或文件夹,则书签将过时.Apple的文档说明了陈旧性:

isStale

返回时,如果是,则书签数据是陈旧的.您的应用应使用返回的URL创建新书签,并使用它代替现有书签的任何存储副本.

不幸的是,这对我很少有用.它有可能在5%的时间内工作.尝试使用返回的URL创建新书签会导致错误,代码256,并且在控制台中查看会显示来自sandboxd的消息,说明在更新的URL上拒绝文件读取数据.

注意如果重新生成书签确实有效,它似乎只在第一次重新生成时才起作用.如果再次移动/重命名文件夹/文件似乎永远不会工作.

我最初如何创建和存储书签

-(IBAction)bookmarkFolder:(id)sender {
  _openPanel = [NSOpenPanel openPanel];
  _openPanel.canChooseFiles = NO;
  _openPanel.canChooseDirectories = YES;
  _openPanel.canCreateDirectories = YES;
  [_openPanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) {
    if (_openPanel.URL != nil) {
      NSError *error;
      NSData *bookmark = [_openPanel.URL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
                                  includingResourceValuesForKeys:nil
                                                   relativeToURL:nil
                                                           error:&error];
      if (error != nil) {
        NSLog(@"Error bookmarking selected URL: %@", error);
        return;
      }
      NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
      [userDefaults setObject:bookmark forKey:@"bookmark"];
    }
  }];
}
Run Code Online (Sandbox Code Playgroud)

解析书签的代码

-(void)resolveStoredBookmark {
  NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
  NSData *bookmark = [userDefaults …
Run Code Online (Sandbox Code Playgroud)

cocoa nsurl security-scoped-bookmarks

23
推荐指数
1
解决办法
2723
查看次数

startAccessingSecurityScopedResource() 实际上是做什么的?

我正在制作一个沙盒 Mac 应用程序,我使用 NSOpenPanel 获取文件 URL,并将其保存到 UserDefaults 作为安全范围的书签。当我退出并重新启动应用程序时,我可以再次将数据块解析为 URL。

文档说我应该调用startAccessingSecurityScopedResource(),并检查它的返回值。(true当我调用它时确实会返回。)但是如果我不调用它,我仍然有一个已解析的 URL,而且我似乎仍然有权访问它。

什么是startAccessingSecurityScopedResource()真正做到?如果我不打电话,有什么不好的事情会发生吗?

macos nsurl foundation security-scoped-bookmarks

12
推荐指数
1
解决办法
3630
查看次数

应用程序扩展中的安全范围书签

我正在创建一个 TodayWidget 应用程序扩展,它显示有关用户在应用程序目录之外选择的文件夹的信息。

在我的主应用程序中,我可以通过 NSOpenPanel 使用 powerbox 来选择文件夹。然后,我可以将安全范围书签保存到我的 TodayWidget 可访问的应用程序组容器的用户默认值。

TodayWidget 可以读取书签数据,但是当它调用URLByResolvingBookmarkData 时,它会出错:

The file couldn’t be opened because it isn’t in the correct format.

我的主应用程序和 TodayWidget 都具有以下权利:

  • com.apple.security.files.bookmarks.app-scope
  • com.apple.security.files.user-selected.read-only

根据 Apple 的文档,只有创建安全范围书签的应用程序才能使用它。我猜这些意味着不允许嵌入式应用程序?

我已经考虑使用 XPC,但这并不能真正解决问题,因为 XPC 也不能使用安全范围的书签,只能使用普通书签。一旦计算机重新启动,XPC 进程将失去对目录的访问权限。

我真正需要的只是一种让 XPC 进程获得对用户指定目录的读取访问权限的方法。有没有办法不必每次重新启动计算机都重新启动我的主应用程序?

macos cocoa xpc security-scoped-bookmarks

6
推荐指数
1
解决办法
1615
查看次数

<StopAccessing> 的 MacOS 内部沙箱错误

我正在构建一个允许用户编辑文件的 MacOS 应用程序。为了访问文件,我使用了一个安全范围的书签,如下所示:

do {
            self.securityScopedBookmark = try asset?.url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
        } catch {
            print("failed bookmark. error info: \(error)")
        }
Run Code Online (Sandbox Code Playgroud)

当用户完成并且 NSDocument 被取消初始化时,我停止访问书签,如下所示:

   deinit {
        if let securityScopedBookmark = self.securityScopedBookmark {
            do {
                var isStale: Bool = false
                
                let url = try URL.init(resolvingBookmarkData: securityScopedBookmark, options: [.withoutUI, .withSecurityScope], relativeTo: nil, bookmarkDataIsStale: &isStale)
                url.stopAccessingSecurityScopedResource()
            } catch let error as NSError {
                print("Bookmark Access Fails: \(error.description)")
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

但是,当尝试调用 .stopAccessingSecurityScopedBookmark() 时,我收到了几个日志错误。

 [scoped] handle 0: sandbox_extension_release error [22: Invalid argument] …
Run Code Online (Sandbox Code Playgroud)

macos sandbox entitlements appstore-sandbox security-scoped-bookmarks

6
推荐指数
0
解决办法
168
查看次数

文件夹的 macOS 安全范围 URL 书签

我在应用程序启动之间为文件夹“重用”安全范围 URL 书签时遇到问题(在 Mojave 和 Catalina 上)。

这是使用libarchive框架的简单解压缩应用程序。用户选择要解压缩的文件,我想为它的父文件夹(例如 ~/Desktop)存储 URL 书签,并在用户下次尝试在同一文件夹中解压缩文件时重新使用它。

首先,我在我的应用程序的权利文件中添加了以下内容:

<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.bookmarks.app-scope</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
Run Code Online (Sandbox Code Playgroud)

第一次访问文件(分别为父文件夹)时:

  1. 用户选择要解压的文件
  2. 我提出NSOpenPanel以获取对文件夹的访问权限:
let directoryURL = fileURL.deletingLastPathComponent()

let openPanel = NSOpenPanel()
openPanel.allowsMultipleSelection = false
openPanel.canChooseDirectories = true
openPanel.canCreateDirectories = false
openPanel.canChooseFiles = false
openPanel.prompt = "Grant Access"
openPanel.directoryURL = directoryURL

openPanel.begin { [weak self] result in
    guard let self = self else { return }
    // WARNING: It's absolutely necessary to access NSOpenPanel.url property to get access
    guard …
Run Code Online (Sandbox Code Playgroud)

macos appstore-sandbox security-scoped-bookmarks swift

5
推荐指数
2
解决办法
1126
查看次数

安全范围内的书签-书签可解决,但仍无法访问文件

编辑:在底部添加的其他信息

我有一个基于文档的沙盒应用程序,该程序将用户选择的QuickTime影片加载到AVPlayer中,并且一切运行正常。

现在,我正在升级代码,以便它将使用Security Scoped书签来获取URL,而不仅仅是存储URL字符串,以便持久存储将允许在重新启动应用程序时加载影片。创建书签后,它将存储在托管对象的Data变量中。

由于某些原因,这破坏了AVPlayer。虽然我已经从用户选择的URL创建了书签,并且可以在重新启动应用程序时从书签中解析URL,但是电影无法正确地加载到AVPlayer中,我不知道为什么...我已经确认从书签解析的URL确实指向电影文件。

我还为项目添加了适当的权利。

这是我的代码:

用户选择要加载的电影并创建书签的功能

 @IBAction func loadMovie(_ sender: Any) {

    let openPanel = NSOpenPanel()
    openPanel.title = "Select Video File To Import"
    openPanel.allowedFileTypes = ["mov", "avi", "mp4"]

    openPanel.begin { (result: NSApplication.ModalResponse) -> Void in
        if result == NSApplication.ModalResponse.OK {

            self.movieURL = openPanel.url
            self.player = AVPlayer.init(url: self.movieURL!)

            self.setupMovie()

            if self.loadedMovieDatabase.count > 0 {
                print("Movie Object Exists. Adding URL String")
                self.loadedMovieDatabase[0].urlString = String(describing: self.movieURL!)
            } else {
                print("No Movie Object Exists Yet.  Creating one and adding URL String")
                let …
Run Code Online (Sandbox Code Playgroud)

avplayer security-scoped-bookmarks swift

1
推荐指数
1
解决办法
922
查看次数

解析 iOS URL 书签数据最终开始失败

我有一个 iOS 应用程序,我正在尝试使用 UserDefaults 保留并重新加载书签数据。似乎工作正常,但我遇到一个问题,有时从书签数据到 URL 的转换失败。它似乎在一段时间内工作正常(甚至在应用程序终止和重新启动等情况下),但最终书签数据将失败(可能在几个小时后?)。

\n\n

因此,在解析书签数据时,如下所示:

\n\n

let url = try URL(resolvingBookmarkData: data, bookmarkDataIsStale: &isStale)

\n\n

抛出捕获的异常并附带描述:Error Domain=NSCocoaErrorDomain Code=4 "The file doesn\xe2\x80\x99t exist."

\n\n

我将书签作为数据存储在 UserDefaults 中。我简单地使用以下内容创建书签数据:

\n\n

let bookmarkData = try url.bookmarkData(options: .minimalBookmark)

\n\n

有趣的是,如果我再次从文档选择器中手动选择相同的文件,则存储在 UserDefaults 中的原始书签将再次可访问。

\n\n

我已经审查了 GitHub 中的开源代码,没有发现我的实现与其他实现有任何本质上的不同。寻找有关可能导致此问题的原因的任何提示或想法。

\n

nsurl ios security-scoped-bookmarks swift

1
推荐指数
1
解决办法
838
查看次数