2012-01-18 61 views
6

我在本地存储了一个加密的word/excel/pdf文件,我需要在iPad应用程序中进行预览。我明白,可以使用QLPreviewController或UiDocumentInteractionController来预览这些文件。我可以很好地使用这个使用QuickLook框架或UiDocumentInteractionController显示加密文件

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

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

但该文件被加密,当我解密它时,我会得到NSData对象。我如何去加载这些NSData中的任何一个。

此外我明白,我可以非常好地将NSData存储为本地文件并将其加载到预览中。但有一个限制,不在本地存储未加密的文件。

如果有人已经完成了这一点,并可以帮助我在这里,将不胜感激。

感谢 AJ

回答

11

由于您使用的是Quick Look,因此您的选项有限。您必须给Quick Look一个NSURL,这意味着它必须位于文件系统(或Internet)上。幸运的是,这应该不是什么大问题。 iOS设备使用硬件级加密。当您的文件被加密时,只有您的应用程序拥有解密密钥。所以,你的文件仍然会被加密,但它也会被你的应用程序和只有你的应用程序读取。

这里就是你要做的:

  1. 解密文件到NSData对象,你已经完成。

  2. 将文件写入不会将上传到iCloud,也不支持iTunes。 tmp目录可能是最佳选择。该代码看起来是这样的:

    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. 
    } 
    

    此时你有一个NSURL,你可以用Quick Look使用。不要忘记在完成解密文件时删除解密文件。

有需要注意的磁盘加密的几件事情:

  1. 它仅支持iOS 4.0以上版本。

  2. 它可能不适用于“旧”设备。

  3. 用户必须拥有活动的密码。

  4. 如果使用NSDataWritingFileProtectionComplete,则该设备处于锁定状态时无法访问该文件。如果您需要在应用锁定时访问该文件,则应该使用NSDataWritingFileProtectionCompleteUnlessOpenNSFileProtectionCompleteUntilFirstUserAuthentication。即使设备被盗和越狱,这仍然会给你很大的保护。要知道,虽然,这些加密选项仅适用于iOS 5.0及

对于对磁盘加密的详细信息,请查看iOS App Programming Guide

+0

感谢Rob的回应。这些信息确实有帮助。我对此有一个后续问题。我正在做所有这些,以便在我的应用程序中提供脱机功能。你认为我自己通过加密和解密文件来增加冗余吗?相反,您认为它的安全性足以让我只使用磁盘加密并将文件存储在应用程序的文档文件夹中。另外什么是最好的地方来存储这些文件。我的意思是文件或tmp文件夹。 再次感谢。 – 2012-02-02 16:00:50

+0

对不起,你已经回答了什么是最好的地方来存储它们。 – 2012-02-02 16:12:52

+0

另外我尝试使用NSDataWritingFileProtectionComplete属性将文件写入模拟器上应用程序的tmp文件夹。我能够到我的文件系统中的文件夹并打开文档。我假设在越狱设备上会出现类似的行为,我可以访问设备的文件系统,并且可以遍历到临时文件夹并访问文档。这是一个正确的假设。 谢谢 – 2012-02-02 18:19:08

0

的一种方法是。

使用临时目录,保存临时文件,使NSURL从该临时文件和显示,然后删除那个临时目录。

谢谢。

+0

是的。那将是我最后的手段。 – 2012-01-31 15:22:56

1

做一些挖后,我发现QLPreviewController在下面使用UIWebView,并调用loadRequest:加载所请求的文件。

另一种方式来完成你的愿望是,就UIWebView, 和使用方法交叉混合的私人类别覆盖loadRequest:方法,并调用代替loadData:MIMEType:textEncodingName:baseURL:方法。

当心:出现

1)在低存储器的场景(即大的文件)的黑色屏幕 “错误加载文档”,如果你关注。 ( unhacked QLPreviewController知道如何处理这些场景 很好,并呈现文档)。

2)我不确定苹果是否会通过 来批准这种黑客行为,尽管这里没有使用私有API 。

代码:

@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

其实,写一个文件到tmp目录仍是不安全的。另一种选择是使用带有NSURLProtocol的UIWebView,并允许即时解密这些数据。

相关问题