I have an encrypted word/excel/pdf file locally stored which I need to preview in my iPad app. I understand that QLPreviewController or UiDocumentInteractionController could be used to preview these files. I can very well use this
- (id <QLPreviewItem>) previewController: (QLPreviewController *) controller previewItemAtIndex: (NSInteger) index {
return [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:[documents objectAtIndex:index] ofType:nil]];
}
But the file is encrypted and when I decrypt it I would get hold of NSData object. How do I go about loading NSData in either of these.
Also I understand that I can very well store the NSData back as a local file and load it in Preview. But there is a constraint of not storing the unencrypted file locally.
If someone has already accomplished this and can help me out here it will be greatly appreciated.
Thanks AJ
One way could be.
use Temp Dir , Save File in Temp , Make NSURL From that Temp File and Display and then Delete that temp Dir after that.
Thanks.
Actually, writing a file to a tmp directory is still insecure. The other alternative is to use UIWebView with NSURLProtocol and allow decrypting this data on the fly.
After doing some digging, I found out that
QLPreviewController
is usingUIWebView
underneath, and calls theloadRequest:
to load the requested file.Another way to accomplish what you desire is to make a private Category on
UIWebView
, and use method swizzling to override theloadRequest:
method, and call instead theloadData:MIMEType:textEncodingName:baseURL:
method.Beware that:
1) In low-memory scenarios (i.e. large files) a black screen with "Error to load the document" appears, if that concerns you. (The unhacked QLPreviewController knows how to handle these scenarios very well and present the document).
2) I'm not sure Apple are going to approve this kind of hack, although no private APIs are used here.
code:
Since you are using
Quick Look
, your options are limited. You must giveQuick Look
anNSURL
, which means it must be on the file system (or the Internet). Fortunately, this shouldn't be much of a problem. iOS devices use hardware-level encryption. When your file is encrypted, only your app has the key to decrypt it. So, your file will still be encrypted, but it will also be readable by your app and only your app.Here's what you do:
Decrypt your file into an
NSData
object, which you've already done.Write the file to a location that will not get uploaded to iCloud nor backed up by iTunes. The
tmp
directory is probably the best choice. The code looks something like this:At this point you have an NSURL which you can use with
Quick Look
. Don't forget to delete the decrypted file when you are done with it.There are a few things to note about on-disk encryption:
It is only supported on iOS 4.0+.
It may not work on "older" devices.
The user must have an active passcode.
If you use
NSDataWritingFileProtectionComplete
, the file is not accessible while the device is locked. If you need to access the file while the app is locked, then you should useNSDataWritingFileProtectionCompleteUnlessOpen
orNSFileProtectionCompleteUntilFirstUserAuthentication
instead. This will still give you great protection, even if the device is stolen and jailbroken. Be aware, though, that these encryption options are only available on iOS 5.0+For more details for on-disk encryption, check out the iOS App Programming Guide