Skip to content

Instantly share code, notes, and snippets.

@dehlen
Created April 29, 2020 19:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dehlen/1fce47792bc4ef676557947895be2ccd to your computer and use it in GitHub Desktop.
Save dehlen/1fce47792bc4ef676557947895be2ccd 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)")
}
}
}
}
}
@dehlen
Copy link
Author

dehlen commented May 30, 2022

Thats what saveBookmarksData and loadBookmarks are for, so yes saving directory access should be possible with this snippet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment