Read and write permission for user selected folder in Mac OS app?

前端 未结 3 1228
清歌不尽
清歌不尽 2020-12-30 12:12

I am developing MAC OS app which have functionality to create file on the behalf of your. First user select folder for storing file (One time at start of app) and then user

3条回答
  •  天涯浪人
    2020-12-30 12:51

    Here is my Answer How to do implement and persist Read and write permission of user selected folder in Mac OS app?

    GitHub Example Project link

    First :

    Add user-selected and bookmarks.app permissions in entitlement file :

    com.apple.security.files.user-selected.read-write
    
    com.apple.security.files.bookmarks.app-scope
    
    

    Then i created class for all bookmark related function required for storeing, loading ... etc bookmarks app.

    import Foundation
    import Cocoa
    
    var bookmarks = [URL: Data]()
    
    func openFolderSelection() -> URL?
    {
        let openPanel = NSOpenPanel()
        openPanel.allowsMultipleSelection = false
        openPanel.canChooseDirectories = true
        openPanel.canCreateDirectories = true
        openPanel.canChooseFiles = false
        openPanel.begin
            { (result) -> Void in
                if result.rawValue == NSApplication.ModalResponse.OK.rawValue
                {
                    let url = openPanel.url
                    storeFolderInBookmark(url: url!)
                }
        }
        return openPanel.url
    }
    
    func saveBookmarksData()
    {
        let path = getBookmarkPath()
        NSKeyedArchiver.archiveRootObject(bookmarks, toFile: path)
    }
    
    func storeFolderInBookmark(url: URL)
    {
        do
        {
            let data = try url.bookmarkData(options: NSURL.BookmarkCreationOptions.withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
            bookmarks[url] = data
        }
        catch
        {
            Swift.print ("Error storing bookmarks")
        }
    
    }
    
    func getBookmarkPath() -> String
    {
        var url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL
        url = url.appendingPathComponent("Bookmarks.dict")
        return url.path
    }
    
    func loadBookmarks()
    {
        let path = getBookmarkPath()
        bookmarks = NSKeyedUnarchiver.unarchiveObject(withFile: path) as! [URL: Data]
        for bookmark in bookmarks
        {
            restoreBookmark(bookmark)
        }
    }
    
    
    
    func restoreBookmark(_ bookmark: (key: URL, value: Data))
    {
        let restoredUrl: URL?
        var isStale = false
    
        Swift.print ("Restoring \(bookmark.key)")
        do
        {
            restoredUrl = try URL.init(resolvingBookmarkData: bookmark.value, options: NSURL.BookmarkResolutionOptions.withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale)
        }
        catch
        {
            Swift.print ("Error restoring bookmarks")
            restoredUrl = nil
        }
    
        if let url = restoredUrl
        {
            if isStale
            {
                Swift.print ("URL is stale")
            }
            else
            {
                if !url.startAccessingSecurityScopedResource()
                {
                    Swift.print ("Couldn't access: \(url.path)")
                }
            }
        }
    
    }
    

    Then open folder selection using NSOpenPanel so the user can select which folders to give you access to. The NSOpenPanel must be stored as a bookmark and saved to disk. Then your app will have the same level of access as it did when the user selected the folder.

    To open NSOpenPanel :

    let selectedURL = openFolderSelection()
    saveBookmarksData()
    

    and to load existing bookmark after app close :

    loadBookmarks()
    

    Thats it. I Hope it will help someone.

提交回复
热议问题