2012-01-18 25 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,並允許即時解密這些數據。

相關問題