File access in a sandboxed Mac app with swift

前端 未结 3 772
被撕碎了的回忆
被撕碎了的回忆 2021-02-02 01:14

I am working on an app for OS X 10.9 with swift, sandboxed.

The app needs access to a SQLite database file. I let the user choose/open a file with NSOpenPanel. I then sa

3条回答
  •  春和景丽
    2021-02-02 01:28

    Here's more clean solution with SWIFT 5.0:

    import Foundation
    import Cocoa
    
    
        class BookmarkManager {
            static let manager = BookmarkManager()
            // Save bookmark for URL. Use this inside the NSOpenPanel `begin` closure
            func saveBookmark(for url: URL){
    
                guard let bookmarkDic = self.getBookmarkData(url: url),
                    let bookmarkURL = getBookmarkURL() else{
                        print("Error getting data or bookmarkURL")
                        return
                }
    
                do
                {
                    let data = try NSKeyedArchiver.archivedData(withRootObject: bookmarkDic, requiringSecureCoding: false)
                    try data.write(to: bookmarkURL)
                    print("Did save data to url")
                }
                catch
                {
                    print("Couldn't save bookmarks")
                }
            }
    
            // Load bookmarks when your app launch for example
            func loadBookmarks()
            {
    
                guard let url = self.getBookmarkURL() else {
                    return
                }
    
                if self.fileExists(url)
                {
                    do
                    {
                        let fileData = try Data(contentsOf: url)
                        if let fileBookmarks = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(fileData) as! [URL: Data]?
                        {
                            for bookmark in fileBookmarks{
                                self.restoreBookmark(key: bookmark.key, value: bookmark.value)
                            }
    
                        }
                    }
                    catch
                    {
                        print ("Couldn't load bookmarks")
                    }
    
                }
            }
    
            private func restoreBookmark(key: URL, value: Data){
                let restoredUrl: URL?
                var isStale = false
    
                Swift.print ("Restoring \(key)")
                do
                {
                    restoredUrl = try URL.init(resolvingBookmarkData: 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)")
                        }
                    }
                }
            }
            private func getBookmarkData(url: URL) -> [URL: Data]?{
                let data = try? url.bookmarkData(options: NSURL.BookmarkCreationOptions.withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
                if let data = data{
                    return [url: data]
                }
                return nil
            }
    
            private func getBookmarkURL() -> URL? {
                let urls = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)
                if let appSupportURL = urls.last{
                    let url = appSupportURL.appendingPathComponent("Bookmarks.dict")
                    return url
                }
                return nil
            }
    
            private func fileExists(_ url: URL) -> Bool
            {
                var isDir = ObjCBool(false)
                let exists = FileManager.default.fileExists(atPath: url.path, isDirectory: &isDir)
    
                return exists
            }
    
        }
    

提交回复
热议问题