You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在File Provider Extension中解析主应用创建的安全范围书签?

主应用生成的安全范围书签无法在File Provider Extension中解析

我正在开发一款包含主应用和File Provider Extension的macOS应用,核心流程如下:

  • 主应用通过NSOpenPanel请求用户授权访问目标目录(优先选择云端驱动器目录)
  • 用户选择文件夹后,将对应URL以安全范围书签的形式保存到共享App Group容器中
  • 尝试在File Provider Extension中解析该书签,用于挂载虚拟文件系统,但解析操作始终失败

已确认的关键信息:

  • 已通过App Group实现主应用与扩展的数据共享
  • 书签数据已成功保存,扩展中能获取到完整的648字节数据
  • 已知安全范围书签与应用沙箱身份绑定,且Apple建议主应用与Extension使用不同的Bundle Identifier,这大概率是导致解析失败的核心原因

以下是用于保存和解析书签的代码实现:

import Foundation

class BookmarkManager {
    static let appGroupID = "group.4V5EJ36UMX.myProduct"
    static let bookmarkFilename = "bookmark.data"

    static var sharedContainerURL: URL? {
        return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupID)
    }

    static var bookmarkFileURL: URL? {
        return sharedContainerURL?.appendingPathComponent(bookmarkFilename)
    }

    // 将书签数据保存到App Group容器
    static func saveBookmark(for url: URL) throws {
        let bookmarkData = try url.bookmarkData(
            options: [.withSecurityScope],
            includingResourceValuesForKeys: nil,
            relativeTo: nil
        )

        guard let bookmarkFileURL = bookmarkFileURL else {
            throw NSError(
                domain: "BookmarkManager",
                code: 1,
                userInfo: [NSLocalizedDescriptionKey: "未找到共享容器"]
            )
        }

        if bookmarkData.isEmpty {
            throw NSError(
                domain: "BookmarkManager",
                code: 4,
                userInfo: [NSLocalizedDescriptionKey: "生成的书签数据为空"]
            )
        }

        do {
            try bookmarkData.write(to: bookmarkFileURL)
            print("✅ 书签已保存至: \(bookmarkFileURL.path)")
            let fileSize = try FileManager.default.attributesOfItem(atPath: bookmarkFileURL.path)[.size] as? Int ?? -1
            print("📦 书签文件大小: \(fileSize) 字节")
        } catch {
            print("❌ 写入书签文件失败: \(error)")
            throw error
        }
    }


    // 从App Group容器解析书签数据
    static func resolveBookmark() throws -> URL? {
        guard let bookmarkFileURL = bookmarkFileURL else {
            throw NSError(domain: "BookmarkManager", code: 2, userInfo: [NSLocalizedDescriptionKey: "未找到共享容器"])
        }

        let bookmarkData = try Data(contentsOf: bookmarkFileURL)
        var isStale = false

        let resolvedURL = try URL(resolvingBookmarkData: bookmarkData, options: [.withSecurityScope], relativeTo: nil, bookmarkDataIsStale: &isStale)

        if isStale {
            // 重新保存以更新书签
            try saveBookmark(for: resolvedURL)
        }

        // 启动资源访问(若需要)
        if !resolvedURL.startAccessingSecurityScopedResource() {
            throw NSError(domain: "BookmarkManager", code: 3, userInfo: [NSLocalizedDescriptionKey: "无法访问安全范围资源"])
        }

        return resolvedURL
    }
}

内容的提问来源于stack exchange,提问作者SwiftDeveloper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 20:22:34