How to store file access permissions for Sandboxed apps (security bookmarks)

Rationale: sandbox apps do not allow opening/writing random files on the filesystem, unless the file had been previously opened using Open/Save panel, or is located inside Downloads, Videos and similar dirs. Once the file was opened using open panel, we can save this "allowance token" (called security bookmark) for later, for subsequent app launches.

First, add these to the entitlements:

    <key>com.apple.security.files.bookmarks.app-scope</key>
    <true/>
    <key>com.apple.security.files.user-selected.read-write</key>
    <true/>

Saving bookmark (after the file has been selected):

        let panel = NSOpenPanel()
        panel.canChooseDirectories = false
        panel.canChooseFiles = true
        panel.allowsMultipleSelection = false
        if(panel.runModal() == .OK) {            
            do {
                let securityBookmarkData = try panel.url!.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
                UserDefaults.standard.set(securityBookmarkData, forKey: "myUrlSecurityBookmark")
                self.fileURL = panel.url!
            } catch {
                print("unable to store security bookmark")
            }   
        }

Loading bookmark (upon app launch, for example):

        if let securityBookmarkData = UserDefaults.standard.data(forKey: "myUrlSecurityBookmark") {
            do {
                var isStale: Bool = false
                self.fileURL = try URL(resolvingBookmarkData: securityBookmarkData, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale)
                if(!isStale) {
                    //do something..
                }
            } catch {}

Applying bookmark:

self.fileURL.startAccessingSecurityScopedResource()
// do something with the file
self.fileURL.stopAccessingSecurityScopedResource()
← Back to Articles