вы можете использовать безопасные закладки для этого. Я прикрепил используемый класс:
import Foundation
import Cocoa
public class SecureFolders
{
public static var window: NSWindow?
private static var folders = [URL : Data]()
private static var path: String?
public static func initialize(_ path: String)
{
self.path = path
}
public static func load()
{
guard let path = self.path else { return }
if !FileManager.default.fileExists(atPath: path)
{
return
}
if let rawData = NSData(contentsOfFile: path)
{
let data = Data(referencing: rawData)
if let folders = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? [URL : Data]
{
for folder in folders
{
self.restore(folder)
}
}
}
}
public static func remove(_ url: URL)
{
folders.removeValue(forKey: url)
}
public static func store(url: URL)
{
guard let path = self.path else { return }
do
{
let data = try NSKeyedArchiver.archivedData(withRootObject: self.folders, requiringSecureCoding: false)
self.folders[url] = data
if let url = URL(string: path)
{
try? data.write(to: url)
}
}
catch
{
Swift.print("Error storing bookmarks")
}
}
public static func restore(_ folder: (key: URL, value: Data))
{
let restoredUrl: URL?
var isStale = false
do
{
restoredUrl = try URL.init(resolvingBookmarkData: folder.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)")
}
self.folders[url] = folder.value
}
}
}
public static func allow(folder: String, prompt: String, callback: @escaping (URL?) -> ())
{
let openPanel = NSOpenPanel()
openPanel.directoryURL = URL(string: folder)
openPanel.allowsMultipleSelection = false
openPanel.canChooseDirectories = true
openPanel.canCreateDirectories = false
openPanel.canChooseFiles = false
openPanel.prompt = prompt
openPanel.beginSheetModal(for: self.window!)
{
result in
if result == NSApplication.ModalResponse.OK
{
let url = openPanel.url
self.store(url: url!)
callback(url)
}
else
{
callback(nil)
}
}
}
public static func isStored(_ directory: Directory) -> Bool
{
return isStored(path: IO.getDirectory(directory))
}
public static func remove(_ directory: Directory)
{
let path = IO.getDirectory(directory)
self.remove(path)
}
public static func remove(_ path: String)
{
let url = URL(fileURLWithPath: path)
self.remove(url)
}
public static func isStored(path: String) -> Bool
{
let absolutePath = URL(fileURLWithPath: path).path
for url in self.folders
{
if url.key.path == absolutePath
{
return true
}
}
return false
}
public static func areStored(_ directories: [Directory]) -> Bool
{
for dir in directories
{
if isStored(dir) == false
{
return false
}
}
return true
}
public static func areStored(_ paths: [String]) -> Bool
{
for path in paths
{
if isStored(path: path) == false
{
return false
}
}
return true
}
}
Использование:
fileprivate func initialize() // Put a call to this in func applicationDidFinishLaunching(_ aNotification: Notification)
{
let directories = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let path = directories[0].appending("/SecureBookmarks.dict")
SecureFolders.initialize(path)
SecureFolders.load()
}
Чтобы добавить папку в безопасные закладки:
fileprivate func allow(_ path: String)
{
SecureFolders.allow(folder: path, prompt: "Open")
{
result in
// Update controls or whatever
}
}
Незабудьте установить экземпляр окна, необходимый для отображения NSOpenPanel
. Вы можете установить экземпляр в viewDidAppear
одного из ваших NSViewControllers:
override func viewDidAppear()
{
super.viewDidAppear()
SecureFolders.window = NSApplication.shared.mainWindow
}