2012-06-05 2 views
5

Sto sviluppando un'app Mac Store in sandbox che chiede all'utente dove salvare i file scaricati da altrove. Ho questo codice per ottenere la cartella da parte dell'utente (si esclude qualche controllo degli errori):startAccessingSecurityScopedResource non restituisce mai il successo

NSOpenPanel* openPanel = [NSOpenPanel openPanel]; 
[openPanel setAllowsMultipleSelection:NO]; 
[openPanel setCanChooseDirectories:YES]; 
[openPanel setResolvesAliases:YES]; 
NSInteger result = [openPanel runModal]; 
NSArray* urls = [openPanel URLs]; 
NSURL* folderURL = [urls objectAtIndex:0]; 
NSError* error; 
NSData* bookmakeData = [folderURL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope 
          includingResourceValuesForKeys:nil 
              relativeToURL:nil 
                error:&error]; 
_saveFolderBookmark = bookmakeData; 

e quando arriva il momento di spostare un file in questa cartella, ho questo codice:

BOOL isStale; 
NSError* error; 
NSURL* saveFolder = [NSURL URLByResolvingBookmarkData:_saveFolderBookmark 
               options:NSURLBookmarkCreationWithSecurityScope 
             relativeToURL:nil 
            bookmarkDataIsStale:&isStale 
               error:&error]; 
BOOL success = [saveFolder startAccessingSecurityScopedResource]; 

// Move the file somewhere else 
NSWorkspace* workspace = [NSWorkspace sharedWorkspace]; 
NSInteger operationTag; 
BOOL copied = [workspace performFileOperation:NSWorkspaceMoveOperation 
             source:[[self getDocumentsFolder] path] 
            destination:[saveFolder path] 
             files:[NSArray arrayWithObject:filename] 
              tag:&operationTag]; 
[saveFolder stopAccessingSecurityScopedResource]; 

Quale è un sacco di codice da elencare per dire che startAccessingSecurityScopedResource non restituisce mai il successo per me, immediatamente dopo aver ottenuto l'ULR da NSOpenPanel o in una successiva esecuzione, con i dati del segnalibro salvati in NSUserDefaults.

Nel file diritti, tra le altre cose, ho:

<key>com.apple.security.files.bookmarks.app-scope</key> 
<true/> 

C'è qualcosa di sbagliato in questo codice?

+0

Visualizzi messaggi di console? Inoltre, controlla due volte la firma del codice per assicurarti che sia configurato correttamente. – gaige

+0

Nel tuo esempio, non è chiaro da dove viene la matrice 'urls' dopo che il pannello aperto è finito. – gaige

+0

Sono riuscito a modificare la riga ricevendo gli URL quando ho rimosso il controllo degli errori. L'ho rimesso di nuovo. Non ci sono messaggi nella console attorno alla linea che chiama startAccessingSecurityScopedResource. –

risposta

8

Questo è molto semplice. Stai risolvendo NSURLBookmarkCreationWithSecurityScope anziché NSURLBookmarkResolutionWithSecurityScope. Basta cambiare quella linea e dovrebbe funzionare.

(Potrebbe non funzionare durante la stessa sessione in cui si crea il segnalibro, quando si ha già accesso all'URL, perché in questo caso non si dovrebbe chiamarlo, ma nelle corse successive dovrebbe, ovviamente , perché questo è il punto.)

+0

Molto ovvio ora che è indicato. Ti chiedi perché ci sono due diverse costanti. Grazie! –

+2

Se si guarda alla storia, ha senso. Il set originale di segnalibri BookmarkCreation e BookmarkResolution in 10.6 non presentava coppie ben abbinate, quindi erano set di valori di maschera di bit completamente indipendenti e non c'era alcuna possibilità di confusione tra, ad esempio, NSURLBookmarkCreationMinimalBookmark e NSURLBookmarkResolutionWithoutUI. Ma sarebbe bello se avessero aggiunto in qualche modo al compilatore di avvertirti di questo, vero? – abarnert

0

La soluzione corretta è stata data in precedenza, ma ho pensato di aggiungere un'altra possibilità per coloro che stanno avendo lo stesso sintomo (startAccessingSecurityScopedResource non restituisce mai YES). Assicurati di utilizzare l'URL effettivo restituito da Powerbox, che può (probabilmente sarà) diverso dall'URL della risorsa effettiva a cui stai tentando di accedere. Ad esempio, Powerbox restituirà un URL a un percorso, che useresti con startAccessingSecurityScopedResource per accedere a un file specifico sotto quella directory.