最近應(yīng)用中有個需求,是關(guān)于文件的導(dǎo)入和導(dǎo)出的。在網(wǎng)上找了找,并沒有合適的資料以參考學習。索性自己寫一篇,以供記錄和學習使用。
文件的導(dǎo)入和導(dǎo)出在iOS開發(fā)中經(jīng)常會用到。例如應(yīng)用可以導(dǎo)出文檔以便其他應(yīng)用使用,或者允許其他應(yīng)用可以導(dǎo)入文檔到你的應(yīng)用中以便使用。又比如,前幾天一位前同事向我咨詢這種其他應(yīng)用的文件拿來使用的栗子。總而言之,應(yīng)用很廣泛。話不多說,多說無益,是時候亮出真正的技術(shù)了。
忽然發(fā)現(xiàn),并沒有合適的表述方式,索性寫個Demo,用來編寫“iOS-實現(xiàn)文件導(dǎo)入和導(dǎo)出”這篇文章吧!
創(chuàng)建應(yīng)用
新建一個工程,基礎(chǔ)界面如下圖所示,其中:
@property (strong, nonatomic) UIWebView *webView; //用來顯示文件
@property (strong, nonatomic) UIButton *exportFileButton; //導(dǎo)出文件按鈕
@property (strong, nonatomic) UIButton *displayFileButton; //顯示導(dǎo)入文件按鈕

往工程里面拖進一個測試文件:一個PDF文件“test.pdf”,好的,目前已經(jīng)初步完成了一個在資源文件夾中包含一個PDF文檔的iOS應(yīng)用。
導(dǎo)出文檔
將工程里資源文件夾中的PDF文件導(dǎo)出,并使用外部應(yīng)用打開此文件。
首先,在ViewController.m中聲明一個UIDocumentInteractionController類型的變量:
@property (strong, nonatomic) UIDocumentInteractionController *documentController;
UIDocumentInteractionController類提供了應(yīng)用內(nèi)用戶文件交互的支持。在這個例子中,你會使用它來導(dǎo)出文檔。
實現(xiàn)以下方法:
- (void)openDocumentInResourceFolder {
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"pdf"];
_documentController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:filePath]];
_documentController.delegate = self;
_documentController.UTI = @"com.adobe.pdf";
[_documentController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
}
#pragma mark - UIDocumentInteractionControllerDelegate
- (void)documentInteractionController:(UIDocumentInteractionController *)controller willBeginSendingToApplication:(NSString *)application {
}
- (void)documentInteractionController:(UIDocumentInteractionController *)controller didEndSendingToApplication:(NSString *)application {
}
- (void)documentInteractionControllerDidDismissOpenInMenu:(UIDocumentInteractionController *)controller {
}
-(void)openDocumentInResourceFolder;
這個方法用來創(chuàng)建一個指向需要導(dǎo)出PDF文件的路徑,通過它來關(guān)聯(lián)UIDocumentInteractionController對象。
需要設(shè)置UTI(Uniform Type Identifiers,唯一類型標識)以便能讓系統(tǒng)找到合適的應(yīng)用來打開你的文檔。在這個例子中,設(shè)置為“com.adobe.pdf”,表示PDF文檔。其他的常用UTI有如“public.html”(HTML文檔)、“public.jpeg”(JPEG文件)等。
更多標識可以查閱Apple官方文檔
其他方法是UIDocumentInteractionControllerDelegate代理方法。在本Demo中可以不實現(xiàn)這三個方法。
最后,在-(void)exportFileButtonClick方法中,添加如下代碼:
- (void)exportFileButtonClick:(id)sender {
[self openDocumentInResourceFolder];
}
真機測試Demo,點擊“導(dǎo)出到其他應(yīng)用顯示”按鈕(exportFileButton)運行如下圖所示:

選擇任一個支持打開文檔格式的外部應(yīng)用,就將文檔導(dǎo)出到外部應(yīng)用中。
導(dǎo)入文檔
在iOS中,一般有兩種方法導(dǎo)入文檔
- 通過iTunes導(dǎo)入文檔
- 應(yīng)用間的文件交換
1.通過iTunes導(dǎo)入文檔
通過iTunes導(dǎo)入文檔,是用一種比較簡單和直接的方式。用戶可以傳入或傳出一些較大的文件到應(yīng)用中。
在Info.plist中,添加鍵UIFileSharingEnabled如下:
Show Raw Keys/Values 模式下

非Show Raw Keys/Values 模式下

運行Demo程序。然后打開iTune,選擇設(shè)備,然后選擇“應(yīng)用”

只要把文件拖進右側(cè)文件共享,應(yīng)用中。所有傳入的文件都會放置在應(yīng)用沙盒中的Documents文件夾中。

當然,先前導(dǎo)入的文件也會在這里顯示,完全可以選擇文件,然后選擇“存儲到...”將應(yīng)用中的文件保存到電腦中。
好了,我們已經(jīng)運用**
![Uploading 通過iTunes導(dǎo)入文檔并驗證導(dǎo)入成功_807781.png . . .]
**這種方法將文件導(dǎo)入到了應(yīng)用??梢酝ㄟ^添加到ViewController.m中的代碼進行證明:
- (void)displayFileButtonClick:(id)sender {
[self listFilesFromDocumentsFolder];
}
- (void)listFilesFromDocumentsFolder {
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSFileManager *manager = [NSFileManager defaultManager];
NSArray *fileList = [manager contentsOfDirectoryAtPath:documentsDirectory error:nil];
NSMutableString *filesStr = [NSMutableString stringWithString:@"Documents文件夾中文件的名稱: \n"];
for (NSString *str in fileList) {
[filesStr appendFormat:@"%@ \n", str];
}
[self displayAlert:filesStr];
[self loadFileFromDocumentsFolder:fileList[0]];
}
- (void)displayAlert:(NSString *)str {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:str preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleCancel handler:nil];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
}
- (void)loadFileFromDocumentsFolder:(NSString *)filename {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentDirectory stringByAppendingPathComponent:filename];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
[self handleDocumentOpenURL:fileURL];
}
- (void)handleDocumentOpenURL:(NSURL *)url {
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[_webView setUserInteractionEnabled:YES];
[_webView loadRequest:requestObj];
}
運行結(jié)果如圖:

2.應(yīng)用間的文件交換
首先,注冊應(yīng)用。你要使Demo能夠接受PDF類型的文件。
在Info.plist中,添加鍵CFBundleDocumentTypes如下:
Show Raw Keys/Values 模式下

非Show Raw Keys/Values 模式下

CFBundleDocumentTypes鍵:Array類型,它包含一個dictionary數(shù)組,這個dictionary表示你的應(yīng)用可以支持的文檔類型
Item0類型為Dictionary
CFBundleTypeName:文檔類型名
LSHandleRank:應(yīng)用的所有者(以上聲明的這種文件類型的創(chuàng)建者),有Alternate(這種文件類型的另外一個瀏覽者)、None或Default
CFBundleTypeRole:應(yīng)用通過什么方式處理這種文件:Editor、Viewer、Shell或None
LSItemContentTpyes:Array類型,它包含表示這種文件類型的UTI數(shù)組通過以上設(shè)置就可以向IOS注冊你的應(yīng)用,以便可以處理PDF文檔。
當一個PDF類型的文檔傳到應(yīng)用中后,應(yīng)用就會自動調(diào)用方法:application:openURL:options: 該方法必須在application delegate中實現(xiàn)。
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if (url != nil && [url isFileURL]) {
if (self.window.rootViewController && [self.window.rootViewController isKindOfClass:[ViewController class]]) {
ViewController *VC = (ViewController *)self.window.rootViewController;
[VC handleDocumentOpenURL:url]; //handleDocumentOpenURL:公有方法
}
}
return YES;
}
當文檔傳入到應(yīng)用中時,它會被復(fù)制到Document文件夾下的“Inbox”目錄中。以上方法url參數(shù)表示Inbox目錄的路徑。一旦文檔被傳入,你將調(diào)用ViewController類的handleDocumentOpenURL:方法,以便加載文檔到WebView。
運行其他應(yīng)用,打開文檔,選擇使用其他其他應(yīng)用打開,就可以看到如下所示的情形:

好了,暫時就這樣把,對于更多類型的文件導(dǎo)入,可以查閱Apple官方文檔里的UTI進行添加。