2012-06-05 17 views
5

Estoy desarrollando una aplicación Sandboxed Mac App Store que le pregunta al usuario dónde guardar los archivos que descarga desde otro lugar. Tengo este código para obtener la carpeta del usuario (excluyendo comprobación de errores):startAccessingSecurityScopedResource nunca devuelve el éxito

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; 

y cuando llega el momento de mover un archivo en esta carpeta, tengo este código:

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]; 

Que es mucho código para listar para decir que startAccessingSecurityScopedResource nunca devuelve éxito para mí, ya sea inmediatamente después de obtener el ULR de NSOpenPanel o en una ejecución posterior, con los datos de marcadores guardados en NSUserDefaults.

En el archivo de prestaciones, entre otras cosas, que tengo:

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

¿Hay algo malo con este código?

+0

¿Estás viendo algún mensaje de la consola? Además, compruebe dos veces la firma del código para asegurarse de que esté configurado correctamente. – gaige

+0

En su ejemplo, no está claro de dónde viene la matriz 'urls' después de que el panel abierto haya finalizado. – gaige

+0

Logré editar la línea obteniendo urls cuando eliminé la comprobación de errores. Lo volví a poner. No hay mensajes en la consola en la línea llamando a startAccessingSecurityScopedResource. –

Respuesta

8

Este es muy fácil. Se está resolviendo con NSURLBookmarkCreationWithSecurityScope en lugar de NSURLBookmarkResolutionWithSecurityScope. Solo cambia esa línea y debería funcionar.

(Puede que no funcione durante la misma sesión donde crea el marcador, cuando ya tiene acceso a la URL, porque no se supone que debe llamarlo en ese caso. Pero en las ejecuciones posteriores debería, por supuesto , porque ese es todo el punto.)

+0

Muy obvio ahora que está señalado. Te hace preguntarte por qué hay dos constantes diferentes. ¡Gracias! –

+2

Si nos fijamos en la historia, tiene sentido. El conjunto original de marcadores BookmarkCreation y BookmarkResolution en 10.6 no tenía pares muy parecidos, por lo que eran conjuntos completamente independientes de valores de máscara de bits, y no había posibilidad de confusión entre, por ejemplo, NSURLBookmarkCreationMinimalBookmark y NSURLBookmarkResolutionWithoutUI. Pero estaría bien si agregan alguna forma para que el compilador te advierta sobre esto, ¿no es así? – abarnert

0

La solución correcta se ha dado anteriormente, pero pensé que agregaría otra posibilidad para aquellos que están teniendo el mismo síntoma (startAccessingSecurityScopedResource nunca regresando YES). Asegúrese de estar utilizando la URL real devuelta por Powerbox, que puede (probablemente será) diferente a la URL del recurso real al que está intentando acceder. Por ejemplo, Powerbox devolverá una URL a una ruta, que usaría con startAccessingSecurityScopedResource para acceder a un archivo específico debajo de ese directorio.

Cuestiones relacionadas