2012-01-18 11 views
6

Tengo un archivo de palabra/excel/pdf encriptado almacenado localmente que necesito obtener una vista previa en mi aplicación de iPad. Entiendo que QLPreviewController o UiDocumentInteractionController podrían usarse para previsualizar estos archivos. Yo muy bien puedo utilizar esteMostrar archivo encriptado utilizando QuickLook framework o UiDocumentInteractionController

- (id <QLPreviewItem>) previewController: (QLPreviewController *) controller previewItemAtIndex: (NSInteger) index { 

    return [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:[documents objectAtIndex:index] ofType:nil]]; 
} 

embargo, el archivo está cifrado y cuando descifrarlo me gustaría conseguir el asimiento de objeto NSData. ¿Cómo hago para cargar NSData en cualquiera de estos?

También entiendo que puedo almacenar el NSData como un archivo local y cargarlo en Vista previa. Pero existe una limitación de no almacenar el archivo no encriptado localmente.

Si alguien ya ha logrado esto y puede ayudarme aquí será muy apreciado.

Gracias AJ

Respuesta

11

Dado que está utilizando Quick Look, sus opciones son limitadas. Debe dar Quick Look un NSURL, lo que significa que debe estar en el sistema de archivos (o Internet). Afortunadamente, esto no debería ser un gran problema. Los dispositivos iOS usan encriptación a nivel de hardware. Cuando su archivo está encriptado, solo su aplicación tiene la clave para descifrarlo. Por lo tanto, su archivo aún estará encriptado, pero también podrá ser leído por su aplicación y solo su aplicación.

Esto es lo que hace:

  1. descifrar el archivo en un objeto NSData, que ya lo ha hecho.

  2. Escriba el archivo en una ubicación que no se cargue en iCloud ni respaldado por iTunes. El directorio tmp es probablemente la mejor opción. El código es como la siguiente:

    NSData * data = // Your decrypted file data. 
    NSString * fileName = // Whatever you want to name your file. 
    NSString * path = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName]; 
    NSURL * url = [NSURL URLWithString:path]; 
    NSError * error = nil; 
    
    BOOL success = [data writeToURL:url 
             options:NSDataWritingFileProtectionComplete 
              error:&error]; 
    if (success) { 
        // Give the URL to Quick Look. 
    } 
    else { 
        // An error happened. See the 'error' object for the details. 
    } 
    

    En este punto usted tiene una NSURL que se puede utilizar con Quick Look. No olvides eliminar el archivo descifrado cuando hayas terminado con él.

Hay algunas cosas a tener en cuenta sobre el cifrado en disco:

  1. Sólo es compatible con iOS 4.0 o superior.

  2. Es posible que no funcione en dispositivos "antiguos".

  3. El usuario debe tener un código de acceso activo.

  4. Si utiliza NSDataWritingFileProtectionComplete, no se puede acceder al archivo mientras el dispositivo está bloqueado.Si necesita acceder al archivo mientras la aplicación está bloqueada, en su lugar debe usar NSDataWritingFileProtectionCompleteUnlessOpen o NSFileProtectionCompleteUntilFirstUserAuthentication. Esto aún le dará una gran protección, incluso si el dispositivo es robado y jailbreak. Tenga en cuenta, sin embargo, que estas opciones de cifrado sólo están disponibles en iOS 5.0+

Para más detalles para el cifrado en el disco, disfrutar de los iOS App Programming Guide

+0

Gracias Rob por la respuesta. Esta información realmente ayudó. Tengo una pregunta de seguimiento sobre esto. Estoy haciendo todo esto para proporcionar capacidad fuera de línea en mi aplicación para los archivos. ¿Crees que estoy agregando redundancia mediante el cifrado y descifrado de archivos por mi cuenta? En su lugar, ¿cree que es lo suficientemente seguro como para utilizar el cifrado en disco y almacenar los archivos en la carpeta de documentos de la aplicación? Además, ¿cuál sería el mejor lugar para almacenar estos archivos? Me refiero a documentos o carpeta tmp. Gracias de nuevo. –

+0

Lamentamos que ya hayas respondido cuál sería el mejor lugar para guardarlos. –

+0

También traté de usar el atributo NSDataWritingFileProtectionComplete para escribir archivos en la carpeta tmp de la aplicación en un simulador. Pude ir a la carpeta en mi sistema de archivos y abrir los documentos. Supongo que habrá un comportamiento similar en un dispositivo con jailbreak en el que tengo acceso al sistema de archivos del dispositivo y puedo atravesar la carpeta temporal y acceder a los documentos. Es esa una suposición correcta. Gracias –

0

Una forma podría ser.

use Temp Dir, guarde el archivo en la temperatura, haga NSURL desde ese archivo temporal y despliegue y luego elimine ese directorio temporal después de eso.

Gracias.

+0

Sí. Ese va a ser mi último recurso. –

1

Después de hacer algo de investigación, descubrí que QLPreviewController está usando UIWebView debajo, y llama al loadRequest: para cargar el archivo solicitado.

Otra manera de lograr lo que desea es hacer una Categoría privada en UIWebView, y método de uso swizzling reemplazar el método loadRequest:, y llame a su lugar el método loadData:MIMEType:textEncodingName:baseURL:.

Tenga en cuenta que: aparece

1) En situaciones de poca memoria (es decir, archivos de gran tamaño) una pantalla en negro con "Error al cargar el documento", en caso de que usted se refiere. (El Deshacando QLPreviewController sabe cómo manejar estos escenarios muy bien y presenta el documento).

2) No estoy seguro de que Apple vaya a para aprobar este tipo de pirateo, aunque no se usan API privadas aquí.

código:

@implementation UIWebView (QLHack) 

    - (void)MyloadRequest:(NSURLRequest *)request 
    { 
     // Check somehow that it's the call of your QLPreviewController   
     // If not, just call the original method. 

     if (!insideQLPreviewController) 
     { 
      // Call original implementation 
      [self MyloadRequest:request];  
     } 
     else 
     { 
      // Load the real data you want 
      [self loadData:data MIMEType:mimeType textEncodingName:nil baseURL:someURL]; 
     } 

    } 

    + (void)load 
    { 
     method_exchangeImplementations(class_getInstanceMethod(self, @selector(loadRequest:)), class_getInstanceMethod(self, @selector(MyloadRequest:))); 
    } 

@end 
1

En realidad, escribir un archivo en un directorio tmp es todavía inseguro. La otra alternativa es usar UIWebView con NSURLProtocol y permitir descifrar esta información sobre la marcha.

Cuestiones relacionadas