// // FileBookmarkService.swift // MyPass // import Foundation /// Persists a security-scoped bookmark for the user's KDBX file in the shared App Group. public final class FileBookmarkService { private static let key = "kdbxBookmark" private let defaults: UserDefaults public init(appGroup: String = "group.org.antiloop222.mypass") { defaults = UserDefaults(suiteName: appGroup) ?? .standard } public func save(url: URL) throws { let data = try url.bookmarkData( options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil ) defaults.set(data, forKey: Self.key) } /// Returns the resolved URL, starting security access. Caller must call `stopAccess(url:)` when done. public func resolveURL() throws -> URL { guard let data = defaults.data(forKey: Self.key) else { throw BookmarkError.notFound } var isStale = false let url = try URL( resolvingBookmarkData: data, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale ) if isStale { let fresh = try url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil) defaults.set(fresh, forKey: Self.key) } guard url.startAccessingSecurityScopedResource() else { throw BookmarkError.accessDenied } return url } public func stopAccess(url: URL) { url.stopAccessingSecurityScopedResource() } public func clear() { defaults.removeObject(forKey: Self.key) } public var hasBookmark: Bool { defaults.data(forKey: Self.key) != nil } } public enum BookmarkError: Error { case notFound case accessDenied }