6

我在本地存储了一个加密的 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]];
}

但是文件是加密的,当我解密它时,我会得到 NSData 对象。我该如何在其中任何一个中加载 NSData 。

另外我知道我可以很好地将 NSData 存储为本地文件并在预览中加载它。但是有一个限制是不能在本地存储未加密的文件。

如果有人已经完成了这项工作并且可以在这里帮助我,我们将不胜感激。

谢谢阿杰

4

4 回答 4

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,则在设备锁定时无法访问该文件。如果您需要在应用程序被锁定时访问该文件,那么您应该使用NSDataWritingFileProtectionCompleteUnlessOpenorNSFileProtectionCompleteUntilFirstUserAuthentication代替。即使设备被盗和越狱,这仍然可以为您提供很好的保护。但请注意,这些加密选项仅适用于 iOS 5.0+

有关磁盘加密的更多详细信息,请查看iOS App Programming Guide

于 2012-02-01T23:12:37.547 回答
1

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

完成您想要的另一种方法是在 上创建一个私有类别UIWebView,并使用方法调配来覆盖该loadRequest:方法,然后调用该loadData:MIMEType:textEncodingName:baseURL:方法。

请注意

1) 在内存不足的情况下(即大文件),如果您担心,会出现带有“加载文档错误”的黑屏。(未破解的 QLPreviewController 知道如何很好地处理这些场景并呈现文档)。

2) 我不确定 Apple 是否会批准这种黑客攻击,尽管这里没有使用私有 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
于 2012-04-29T09:24:17.040 回答
1

实际上,将文件写入 tmp 目录仍然是不安全的。另一种选择是将 UIWebView 与 NSURLProtocol 一起使用,并允许动态解密此数据。

于 2015-05-11T23:52:31.393 回答
0

一种方法可能是。

使用 Temp Dir ,将文件保存在 Temp 中,从该临时文件制作 NSURL 并显示,然后删除该临时目录。

谢谢。

于 2012-01-31T04:43:55.623 回答