Skip to content

Instantly share code, notes, and snippets.

@dehlen
Created October 24, 2025 11:45
Show Gist options
  • Select an option

  • Save dehlen/0597dae2677251f2831669bfbfc05503 to your computer and use it in GitHub Desktop.

Select an option

Save dehlen/0597dae2677251f2831669bfbfc05503 to your computer and use it in GitHub Desktop.
macOS Sandbox Wrapper
import Foundation
import AppKit.NSOpenPanel
class SandboxDirectoryAccess {
static let shared: SandboxDirectoryAccess = SandboxDirectoryAccess()
private var bookmarks = [URL: Data]()
init() {}
func openFolderSelection(then handler: @escaping (URL?) -> Void) {
let openPanel = NSOpenPanel()
openPanel.allowsMultipleSelection = false
openPanel.canChooseDirectories = true
openPanel.canCreateDirectories = true
openPanel.canChooseFiles = false
openPanel.begin { (result) -> Void in
if result == .OK {
if let url = openPanel.urls.first {
self.storeFolderInBookmark(url: url)
}
handler(openPanel.urls.first)
}
}
}
func saveBookmarksData() {
let path = getBookmarkPath()
do {
let data = try NSKeyedArchiver.archivedData(withRootObject: bookmarks, requiringSecureCoding: false)
try data.write(to: path)
} catch {
debugPrint("Could not save bookmark data")
}
}
func loadBookmarks() {
let path = getBookmarkPath()
bookmarks = [:]
if let data = try? Data(contentsOf: path) {
if let unarchived = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) {
bookmarks = unarchived as? [URL: Data] ?? [:]
}
for bookmark in bookmarks {
restoreBookmark(bookmark)
}
}
}
private func storeFolderInBookmark(url: URL) {
do {
let data = try url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
bookmarks[url] = data
} catch {
debugPrint("Error storing bookmarks")
}
}
private func getBookmarkPath() -> URL {
let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL
return url.appendingPathComponent("Bookmarks.dict")
}
private func restoreBookmark(_ bookmark: (key: URL, value: Data)) {
let restoredUrl: URL?
var isStale = false
debugPrint("Restoring \(bookmark.key.absoluteString)")
do {
restoredUrl = try URL(resolvingBookmarkData: bookmark.value, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale)
} catch {
debugPrint("Error restoring bookmarks")
restoredUrl = nil
}
if let url = restoredUrl {
if isStale {
debugPrint("URL is stale")
} else {
if !url.startAccessingSecurityScopedResource() {
debugPrint("Couldn't access: \(url.path)")
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment