2015-07-07 14 views
5

Sto lavorando su un'app per OSX 10.9 con swift, sandboxed. L'app richiede l'accesso a un file di database SQLite. Lascio che l'utente scelga/apra un file con NSOpenPanel. Quindi salvare il percorso del file con NSUserDefaults per un uso successivo.accesso ai file in un'app osx sandbox con swift

Desidero che questo file venga aperto automaticamente ogni volta che si riavvia l'app. Ricevo il percorso memorizzato da NSUserDefault, ma quando apro il file con questo percorso viene visualizzato un errore, che dice che non ho il permesso di accedere al file. (funziona senza sandboxing)

Sembra che i segnalibri siano la soluzione al mio problema.

Esiste un buon tutorial su come utilizzare i segnalibri con swift per un'app osx? Qualche altro suggerimento?

risposta

0

segnalibri con ambito di sicurezza è esattamente la strada da percorrere. buon punto di partenza è la documentazione Apple su sandbox AppStore (che include codice di esempio) e riferimento di classe di NSFileManager.

quindi non si memorizzerà il percorso nelle impostazioni predefinite dell'utente ma i dati binari del segnalibro.

6

Ecco la mia risposta che ho appena ricevuto a lavorare a Swift 3 con un piccolo aiuto da 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 
} 

Per utilizzare questo codice è necessario innanzitutto chiamare NSOpenPanel così l'utente può selezionare le cartelle da dare accesso a. NSOpenPanel deve essere memorizzato come segnalibro e salvato su disco.

let url = allowFolder() 
saveBookmarks() 

Quando si riavvia l'applicazione è necessario chiamare

loadBookmarks() 

allora la vostra applicazione avrà lo stesso livello di accesso come ha fatto quando l'utente ha selezionato la cartella. Spero che questo aiuti qualcuno.