2012-04-21 17 views
16

Estoy sandboxing mi aplicación, y tratando de permitir la importación/exportación de múltiples archivos, utilizando un archivo XML para referirse a ellos. Para permitir que mi aplicación (u otra aplicación de espacio aislado) acceda a los archivos enumerados en el XML, también incluyo un marcador serializado de ámbito de seguridad. Lo estoy serializando como se describe en this answer, y mis pruebas unitarias (que son no sandbox) escriben y leen los datos XML sin problemas. Cuando mi aplicación resuelve el marcador, el NSURL devuelto es nulo, al igual que la referencia NSError. Como no creo que ese debería ser el caso, ¿por qué está sucediendo? Puedo evitarlo al solicitar al usuario que seleccione un archivo/directorio con un NSOpenPanel, pero me gustaría que los marcadores funcionen como deberían.Sandbox de aplicación: el marcador del objetivo del documento no se resuelve; no devuelve ningún error

Reproducido en un proyecto de prueba

de reproducir en casa, cree una nueva aplicación de cacao en Xcode, y utilizar los siguientes Síntesis de los archivos en el proyecto: https://gist.github.com/2582589 (actualizado con una nueva visión correcta loop)

Luego, siga Apple's instructions para firmar con el código del proyecto. Reproduce el problema (que presenté a Apple como rdar://11369377) haciendo clic en los botones en secuencia. Usted elige cualquier archivo en el disco (fuera del contenedor de la aplicación), luego un XML para exportar y luego el mismo XML para importar.

Espero que ustedes puedan ayudarme a descubrir lo que estoy haciendo mal. O bien estoy haciendo algo mal y el marco está ocultándose erróneamente a sí mismo, o lo estoy haciendo bien y está totalmente roto. Intento no hacerlo blame the framework, ¿cuál es? ¿O hay otra posibilidad?

Código de ejemplo

Exportación del XML para docURL:

// After the user picks an XML (docURL) destination with NSSavePanel 

[targetURL startAccessingSecurityScopedResource]; 
NSData *bookmark = [targetURL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope 
         includingResourceValuesForKeys:nil 
             relativeToURL:docURL 
               error:&error]; 
[targetURL stopAccessingSecurityScopedResource]; 

importar el XML de docURL:

// After the user selected the XML (docURL) from an NSOpenPanel 

NSURL *result = [NSURL URLByResolvingBookmarkData:bookmarkData 
              options:NSURLBookmarkResolutionWithSecurityScope 
            relativeToURL:docURL 
           bookmarkDataIsStale:nil 
              error:&error]; 

He intentado que rodea a esta llamada con [docURL ..AccessingSecurityScopedResource], que no lo hizo hacer una diferencia (como se esperaba, ya que el docURL ya está dentro del alcance después de haber sido seleccionado en el panel abierto

Además, se especifica la siguiente en mi app.entitlements archivo:

com.apple.security.files.user-selected.read-write 
com.apple.security.files.bookmarks.app-scope 
com.apple.security.files.bookmarks.collection-scope 

Como se mencionó anteriormente, el segundo paso (la resolución del marcador) completa, pero deja a ambos error y result nulo. Como he estado implementando sandboxing, la mayoría de los errores que he cometido han resultado en la devolución de NSError, lo que me ayudó a resolver el error. Pero ahora no hay ningún error y no se ha resuelto ninguna URL.

Resolución de problemas Varios pasos

  • He intentado colocar el archivo XML en caja de arena de mi aplicación, que no hacen una diferencia, por lo que el acceso al archivo XML no es el problema

  • La aplicación utiliza ARC, pero también lo hacen las pruebas unitarias, que tienen éxito. He intentado utilizar un alloc/init en lugar del método de clase autoreleased, también (por si acaso)

  • me pega el código de resolución URL inmediatamente después de crear el marcador, y funciona muy bien, la producción de una URL de seguridad restringidos al

  • Hice un po en el marcador creado originalmente (antes de la serialización), y luego en el marcador después de la deserialización, y coinciden con el 100%. La serialización no es el problema

  • Reemplacé la llamada de resolución con CFURLCreateByResolvingBookmarkData(..), sin cambios. Si es un error, es presente en la API de base fundamental, así como la capa de cacao

  • Especificación de un valor para bookmarkDataIsStale: no tiene ningún efecto

  • Si especifico 0 para options:, entonces yo hago obtener un NSURL válido, pero no tiene un alcance de seguridad, y por lo tanto las llamadas subsiguientes para leer el archivo aún fallan

    En otras palabras, el marcador deserializado parece ser válido. Si se corrompen los datos de marcador, dudo NSURL sería capaz de hacer cualquier cosa con él

  • NSURL.h no contenía comentarios útiles para señalar algo que estoy haciendo mal

Hay alguien más usar marcadores de documentos de ámbito de seguridad en una aplicación de espacio aislado con éxito? Si es así, ¿qué estás haciendo de manera diferente a como soy?

OS Versión Solicitud

¿Puede alguien con acceso a la beta del león de montaña verificar si es o no es mi proyecto de ejemplo muestra la misma (falta de) de error? Si se trata de un error que se ha solucionado después de Lion, no me preocuparé por ello. Todavía no estoy en el programa de desarrollo y, por lo tanto, no tengo acceso. No estoy seguro si responder esa pregunta violaría la NDA, pero espero que no.

+0

No pude ayudar de todos modos, pero esta pregunta es un poco un registro de viaje a través de su exploración. Sería genial si pudieras volver a trabajar, olvidando CÓMO llegaste a donde lo hiciste. Sin ofender: la pregunta parece ser de alta calidad, lo que reflejan las 5 votaciones ascendentes (ahora 6 con la mía). –

+0

@Yar gracias por la entrada y el voto favorable. Guardé (la mayoría de) las actualizaciones por dos razones. Antes que nada, estoy documentando los pasos que probé para que otros puedan evitar problemas repetitivos, y segundo, publiqué las actualizaciones en la parte inferior (en lugar de trabajar la información nueva en la pregunta principal) para aclarar a los que siguen la pregunta qué realmente cambiado Planeé editar la pregunta después de que fue respondida. ¿Sugiere reorganizar el contenido de la pregunta o eliminar piezas menos relevantes? – Dov

+0

ambos. Aumentará la probabilidad de que te respondan y también hará que la publicación sea más relevante para usuarios futuros que tienen exploraciones totalmente diferentes, pero el mismo problema. Ya sabes, resuma el problema;) –

Respuesta

5

En su código Gist, cambie la línea siguiente en AppDelegate.m (línea 61):

[xmlTextFileData writeToURL:savePanel.URL atomically:YES]; 

a

[xmlTextFileData writeToURL:savePanel.URL atomically:NO]; 

Su código trabajará entonces.

La razón para esto es probablemente la misma razón por la cual es necesario tener un archivo existente (pero vacío) que contendrá los marcadores del ámbito del documento antes de llamar a [anURL bookmarkDataWithOptions]: Al crear la instancia de NSData, ScopedBookmarkAgent agrega algo (como una etiqueta, probablemente un atributo de archivo extendido) a ese archivo.

Si escribe datos (es decir, las URL de marcador) en ese archivo atómicamente, de hecho, no se escriben directamente en el archivo sino primero en un archivo temporal cuyo nombre se cambia si la operación de escritura se realizó correctamente. Parece que la etiqueta que se ha agregado al archivo (vacío, pero existente) que contendrá los marcadores se pierde durante este proceso de escritura en un archivo temporal y luego se cambia el nombre (y por lo tanto probablemente se elimine el archivo original y vacío) .

Dicho sea de paso: no debería ser necesario crear marcadores en el ámbito de la aplicación antes de pasar las respectivas URL al archivo xml que contiene los marcadores del ámbito del documento.

Adición: com.apple.security.files.bookmarks.collection-scope ha cambiado de nombre a com.apple.security.files.bookmarks.document-scope en 10.7.4.

+0

Gracias x1000. Ese pensamiento nunca se me ocurrió. En cuanto a la clave de titularidad renombrada, ¿puedes dar una referencia? La documentación aún dice 'collection-scope'. – Dov

+1

El cambio de nombre de titularidad se menciona en la Tabla 3-4 de [Referencia de clave de titularidad] (https://developer.apple.com/library/mac/#documentation/Miscellaneous/Reference/EntitlementKeyReference/EnablingAppSandbox/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW18). – Tim

+0

@Tim Menciona que "es necesario tener un archivo existente (pero vacío) que contendrá los marcadores del ámbito del documento". ¿Cómo se supone que uno sepa la ubicación en la que el usuario guardará un documento nuevo por primera vez? Además, ¿cómo se crea un archivo vacío en alguna ubicación con sandboxing activado y NSSavePanel no aparece en la imagen? – AmaltasCoder

Cuestiones relacionadas