使用QuickLook框架或UiDocumentInteractionController显示encryption文件

我有一个encryption的word / excel / pdf文件本地存储,我需要预览在我的iPad应用程序。 我明白,QLPreviewController或UiDocumentInteractionController可以用来预览这些文件。 我可以很好地使用这个

- (id <QLPreviewItem>) previewController: (QLPreviewController *) controller previewItemAtIndex: (NSInteger) index { return [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:[documents objectAtIndex:index] ofType:nil]]; } 

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

我也明白,我可以非常好地存储NSData作为本地文件,并加载到预览。 但是有一个限制,不在本地存储未encryption的文件。

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

谢谢AJ

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

这是你做的:

  1. 把你的文件解密成一个你已经完成的NSData对象。

  2. 将文件写入一个不会上传到iCloud的位置, 也不会由iTunes进行备份。 tmp目录可能是最好的select。 代码看起来像这样:

     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 。 当您完成解密文件时,请不要忘记删除解密文件。

磁盘encryption有几点需要注意:

  1. 它仅在iOS 4.0+上受支持。

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

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

  4. 如果您使用NSDataWritingFileProtectionComplete ,则在设备被locking时文件不可访问。 如果您需要在应用程序locking时访问该文件,则应该使用NSDataWritingFileProtectionCompleteUnlessOpenNSFileProtectionCompleteUntilFirstUserAuthentication 。 这将仍然给你很大的保护,即使该设备被盗窃和越狱。 但请注意,这些encryption选项仅适用于iOS 5.0+

有关磁盘encryption的更多详细信息,请参阅iOS应用程序编程指南

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

另一种方法来实现你所期望的是在UIWebView上创build一个私有的类别,并使用方法swizzling来覆盖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 

实际上,将一个文件写入一个tmp目录仍然是不安全的。 另一种select是使用带有NSURLProtocol的UIWebView,并允许即时解密这些数据。

一种方法可能是。

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

谢谢。