如何在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
相关产品推荐
相关产品推荐

