2015-07-07 17 views
5

Ich arbeite an einer App für OSX 10.9 mit Swift, Sandboxed. Die App benötigt Zugriff auf eine SQLite-Datenbankdatei. Ich lasse den Benutzer eine Datei mit NSOpenPanel auswählen/öffnen. Ich speichere dann den Dateipfad mit NSUserDefaults für die spätere Verwendung.Dateizugriff in einer Sandboxed Osx App mit swift

Ich möchte, dass diese Datei jedes Mal automatisch geöffnet wird, wenn die App neu gestartet wird. Ich erhalte den gespeicherten Pfad von NSUserDefault, aber wenn ich die Datei mit diesem Pfad öffne, erhalte ich einen Fehler und sage, dass ich keine Berechtigung habe, auf die Datei zuzugreifen. (es funktioniert ohne Sandboxing)

Es sieht aus wie Lesezeichen sind die Lösung für mein Problem.

Gibt es ein gutes Tutorial, wie man Lesezeichen mit swift für eine osx App verwendet? Irgendwelche anderen Vorschläge?

Antwort

0

Sicherheit scoped Lesezeichen ist genau der Weg zu gehen. Ein guter Ausgangspunkt ist die Apple-Dokumentation in der AppStore-Sandbox (die Beispielcode enthält) und der Klassenreferenz von NSFileManager.

Sie werden dann den Pfad nicht in Benutzerstandardeinstellungen speichern, sondern die Binärdaten des Lesezeichens.

6

Hier ist meine Antwort, die ich in Swift 3 mit ein wenig Hilfe nur haben von http://swiftrien.blogspot.com/2015/07/persisting-file-access-rights-between.html

import Foundation 
import Cocoa 

var bookmarks = [URL: Data]() 

func bookmarkPath() -> String 
{ 
    var url = app.applicationDocumentsDirectory 
    url = url.appendingPathComponent("Bookmarks.dict") 
    return url.path 
} 

func loadBookmarks() 
{ 
    let path = bookmarkPath() 
    bookmarks = NSKeyedUnarchiver.unarchiveObject(withFile: path) as! [URL: Data] 
    for bookmark in bookmarks 
    { 
     restoreBookmark(bookmark) 
    } 
} 

func saveBookmarks() 
{ 
    let path = bookmarkPath() 
    NSKeyedArchiver.archiveRootObject(bookmarks, toFile: path) 
} 

func storeBookmark(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 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)") 
      } 
     } 
    } 

} 

func allowFolder() -> URL? 
{ 
    let openPanel = NSOpenPanel() 
    openPanel.allowsMultipleSelection = false 
    openPanel.canChooseDirectories = true 
    openPanel.canCreateDirectories = true 
    openPanel.canChooseFiles = false 
    openPanel.begin 
     { (result) -> Void in 
      if result == NSFileHandlingPanelOKButton 
      { 
       let url = openPanel.url 
       storeBookmark(url: url!) 
      } 
    } 
    return openPanel.url 
} 

Um diesen Code zu verwenden, arbeiten rufen Sie müssen zuerst NSOpenPanel so kann der Benutzer auswählen, welche Sie geben Ordner Zugriff auf. Das NSOpenPanel muss als Lesezeichen gespeichert und auf dem Datenträger gespeichert werden.

let url = allowFolder() 
saveBookmarks() 

Wenn Sie die Anwendung neu starten, müssen Sie rufen

loadBookmarks() 

dann Ihre Anwendung das gleiche Maß an Zugang haben wird, wie es tut, wenn der Benutzer die Ordner ausgewählt. Hoffe, das hilft jemandem.