问题标签 [security-scoped-bookmarks]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
338 浏览

macos - URL 是否总是会创建具有完全相同字节模式的安全范围书签?

我想在沙盒 Mac 应用程序中维护文件夹列表。为此,我需要制作一个安全范围的书签,使用url.bookmarkData().

对于给定的文件 URL,是否保证Data此方法返回的始终是相同的字节模式?

也就是说,我可以通过仅检查 Data 实例来url.bookmarkData()测试[Data]列表是否包含同一 URL 的安全范围书签吗?还是我需要将每个解析Data为 aURL并进行比较?

0 投票
1 回答
4632 浏览

macos - startAccessingSecurityScopedResource() 实际上做了什么?

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

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

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

0 投票
1 回答
2070 浏览

swift - 安全范围书签 - 书签已解析但仍无法访问文件

编辑:在底部添加了附加信息

我有一个基于文档的沙盒应用程序,可以将用户选择的 quicktime 电影加载到 AVPlayer 中,并且一切正常。

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

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

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

这是我的代码:

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

将书签解析为 URL 并加载电影的功能

我是安全范围书签的新手,所以我希望这对于以前使用过它们的任何人来说都是显而易见的。

我想知道这是否有问题:

也许我叫错了?有时我发现 Apple 的文档含糊不清……任何见解都将不胜感激!

编辑:

我相信我知道为什么会这样,但我不知道如何解决它......

总是返回 FALSE... 根据文档,这意味着它不起作用。此外,虽然电影文件位于我的桌面上,但已解决的 URL 如下所示(这可能是正常的,我不知道。):

file:///Users/me/Library/Containers/myapp/Data/Desktop/sample_on_desktop.mov

苹果文档提到了文档范围不能使用系统中的文件(又名“/Library”)的事实,但是我的权利设置为使用应用程序范围的书签,并且我的书签是使用 relativeURL 的 nil 标志创建的: 所以这应该不是问题。

0 投票
0 回答
177 浏览

macos - App-Scoped vs. Document-Scoped Security-Scoped 书签

快速问题:

我正在 OS X 中开发基于文档的应用程序。我可以使用 App-Scope 书签来访问文件,还是必须是文档范围的书签?

我知道任何应用程序都可以使用这两种方法,但我不确定该应用程序的特定文档是否无法访问应用程序范围书签。

我最初实现了一个基于应用程序的范围书签,当我尝试开始访问它时,它总是返回 FALSE。

想知道我是否需要将其更改为文档范围才能使其正常工作。

这是我的另一个问题的链接,它显示了实际代码:

安全范围书签 - startAccessing 始终返回 FALSE 并且已解析的 URL 不起作用

谢谢!

0 投票
1 回答
431 浏览

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

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

因此,当像这样解析书签数据时:

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

捕获的异常被抛出并带有描述:Error Domain=NSCocoaErrorDomain Code=4 "The file doesn’t exist."

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

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

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

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

0 投票
2 回答
709 浏览

macos - MacOS 沙盒应用程序:无需 NSOpenPanel 即可访问文件

在沙盒化的基于 NSDocument 的应用程序中,可以使用 NSOpenPanel 访问任何兼容的文档,无论文档保存在何处。如果没有 NSOpenPanel,应用程序只能访问沙盒容器中的文件。

由于我的应用程序管理两种类型的子类 NSdocument(文本作为读取器/写入器和图像仅作为读取器),我尝试为图像实现一个单独的“打开最近”菜单。当用户打开它们时,我禁用了它们的普通行为,覆盖了noteNewRecentDocumentURL: (NSURL *)urlNSDocumentController 的方法以返回图像 url 的 NO。这样只有文本文档出现在普通的文件 -> 打开最近的菜单中(当用户选择它们时正常打开)。图像列在自定义菜单中。

这些图像 url 出现问题,因为应用程序是沙盒化的:应用程序无法直接打开专用菜单中列出的任何图像文件(任何读取操作都会返回 -54 错误。可以使用以下方法检查此行为:

FALSE在这种情况下总是返回。只有一个例外:当我从专用的“打开最近”菜单重新打开一个文件时,该文件之前已在同一应用程序会话中使用 NSOpenPanel 打开,然后关闭:在这种情况下isReadableFileAtPath:返回TRUE并且可以访问该文件。但是当应用程序退出并重新启动时,不能以这种方式访问​​最近的图像文件。

我确定了解决此问题的三个解决方案:

  1. 一旦用户“合法”地通过 NSOpenPanel 访问图像文件,就将其移动到沙盒容器中。当然,它可以工作,但会阻止用户自行决定文件的位置!同样,在沙箱中复制文件也不是解决办法。

  2. 在沙箱中为这些文件创建别名。由于我找不到这样做的方法,我无法测试这是否是一个解决方案。

  3. 禁用应用程序沙盒。但这是更糟糕的解决方案,因为使用沙盒的原因有很多!

是否有第四个解决方案,它可以授权对任何图像文件的只读访问,无论它位于何处,而不禁用沙箱?

0 投票
0 回答
173 浏览

macos - 如何从 xpc 服务中的安全范围书签 url 访问文件?

我正在创建沙盒 macOS 应用程序。我从中获取文件 url NSOpenPanel,创建书签数据并保存到数据存储中。然后我可以成功地从书签数据中恢复 url 并从我的应用程序中访问文件数据。

我在项目中还有另一个目标XPC Service,我将恢复的 url 传递给这个目标,但是当我尝试从中读取文件时,我无法访问来自这个 url 的文件XPC Service

我的基本应用程序和XPC Service目标都有 com.apple.security.files.bookmarks.app-scope com.apple.security.files.bookmarks.document-scope com.apple.security.files.user-selected.read-write

我应该怎么做才能从目标中恢复的 url 访问文件XPC Service?我可以从中复制或删除文件XPC Service吗?

基础应用

XPC服务

[NSData dataWithContentsOfURL:anURL]nil

0 投票
0 回答
40 浏览

ios - 如何访问所选文件夹中的所有文件?

用户选择一个包含视频剪辑文件的文件夹,这些文件都是连续的,我的应用程序计划遍历文件夹中的所有文件并将它们组合成一个完整的视频。这通常位于 iCloud、DropBox、box 或其他此类位置。

我正在使用 NSFileCoordinator 和 [NSURL startAccessingSecurityScopedResource] ,这些使文件夹本身可用,但显然不是其中的文件。

有没有办法将文件夹的访问权限扩展到其中的项目?

0 投票
2 回答
1522 浏览

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

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

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

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

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

  1. 用户选择要解压的文件
  2. 我提出NSOpenPanel获得对文件夹的访问权限:
  1. 我获取文件夹URL 的书签数据并将其存储到密钥存档:
  1. 现在我开始使用文件URL 并将libarchive.zip 文件解压缩到它的父文件夹:
  1. 一切都按预期工作,.zip 文件被解压缩

重新启动应用程序时,在同一文件夹中解压缩文件,重用保存的书签数据:

  1. 我从键控存档中获取书签:
  1. 我从文件父文件夹的书签中获取书签数据并解决它:
  1. 现在我再次开始使用文件URL 并使用libarchive将 .zip 文件解压缩到它的父文件夹:

但是这次libarchive返回错误说Failed to open \'/Users/martin/Desktop/Archive.zip\'

我知道我可能做错了什么或者不理解安全范围 URL 书签的概念,但找不到问题所在。有什么提示吗?

最终解决方案 Rckstr 在这个 Apple 开发者论坛帖子中的回答和回答都为我指明了正确的方向。绝对有必要调用startAccessingSecurityScopedResource()由返回的 URL 的相同实例try URL(resolvingBookmarkData: data, options: .withSecurityScope ...

0 投票
1 回答
49 浏览

swift - SwiftySandboxFileAccess UserDefaults 值

SwiftySandboxFileAccess在用户第一次批准 NSOpenPanel 选择时工作,但是下次打开应用程序时,即使 SwiftySandboxFileAccess 认为它​​具有访问权限,只是因为UserDefaults我认为保存了一个值,安全书签也没有访问权限?

这就是SwiftySandboxFileAccess节省UserDefaults

  1. 它在路径bd_的开头添加了什么?file://
  2. 所有这些 8 位的东西是什么?

更多背景:

这就是我尝试使用安全书签的方式:

"access the URL here"...,网址...嗯...

来自: https ://github.com/ConfusedVorlon/SwiftySandboxFileAccess/blob/master/SwiftySandboxFileAccessDemo/SwiftySandboxDemo/Manager.swift#L42

我正在阅读相关的安全书签票证,其中提到安全书签需要保存为 URL,然后传递到要使用它的子进程: https ://stackoverflow.com/a/27321020/1762493

with: {}块已通过此处看到的 SwiftySandboxFileAccess包装在startAccessingSecurityScopedResource/中: https ://github.com/ConfusedVorlon/SwiftySandboxFileAccess/blob/master/SwiftySandboxFileAccess/Classes/SandboxFileAccess.swift#L87stopAccessingSecurityScopedResource

runFileVacuumCLI()作为队列操作运行: