程序間文檔共享

iOS中的沙盒可以讓平臺(tái)更加的安全,這也是沙盒給用戶帶來(lái)的最主要好處。不過(guò)由于沙盒的嚴(yán)格限制,導(dǎo)致程序之間共享數(shù)據(jù)比較麻煩。一般在程序間共享文檔可以通過(guò)UIDocumentInteractionController類實(shí)現(xiàn)通訊。它支持在你的app中用其他app預(yù)覽和顯示文檔。同時(shí)也支持文件關(guān)聯(lián),允許其他app通過(guò)你的程序打開(kāi)文件。這些技術(shù)包括了UIKit中提供的UIDocumentInteractionController類(UIDocumentInteractionController Class Reference),以及Quick Look框架(Quick Look Framework Reference)。

本文將就如何在應(yīng)用之間進(jìn)行文件共享進(jìn)行基本探究。還請(qǐng)大牛勿噴。

蘋(píng)果官方文檔

效果圖

文件共享

跨APP傳文件

預(yù)覽文檔和呈現(xiàn)選項(xiàng)菜單

如果你的app需要打開(kāi)它不支持的文件(PDF文件、圖像文件,等等),或者需要將app的文件傳輸給另外一個(gè)允許接收此類型文件的app時(shí)??梢允褂梦募换タ刂破?UIDocumentInteractionController類的實(shí)例)為用戶提供可接收程序來(lái)處理文件,說(shuō)的簡(jiǎn)單點(diǎn)就是通過(guò)Quick Look框架判斷文檔是否能被另一個(gè)app打開(kāi)和預(yù)覽。

UIDocumentInteractionController在iOS3.2中就已經(jīng)存在了,使用起來(lái)非常靈活,功能也比較強(qiáng)大。它除了支持同設(shè)備上app之間的文檔共享外,還可以實(shí)現(xiàn)文檔的預(yù)覽、打印、發(fā)郵件以及復(fù)制。

要使用一個(gè)文件交互控制器(UIDocumentInteractionController類的實(shí)例),需要以下步驟:

為每個(gè)你想打開(kāi)的文件創(chuàng)建一個(gè)UIDocumentInteractionController類的實(shí)例

實(shí)現(xiàn)UIDocumentInteractionControllerDelegate代理

顯示預(yù)覽窗口/顯示菜單。

一、創(chuàng)建實(shí)例

DocumentInteraction Controller使用靜態(tài)方法interactionControllerWithURL創(chuàng)建實(shí)例,這個(gè)方法使用一個(gè)NSURL作為參數(shù)。

//創(chuàng)建實(shí)例NSURL*filePath = [NSURLfileURLWithPath:path];UIDocumentInteractionController*documentController = [UIDocumentInteractionControllerinteractionControllerWithURL:[NSURLfileURLWithPath:filePath]];

二、顯示預(yù)覽窗口

Document Interaction Controller對(duì)象使用presentPreviewAnimated方法彈出一個(gè)全屏的文檔預(yù)覽窗口。

BOOLb = [documentController presentPreviewAnimated:YES];

三、顯示菜單

如果你不想在本應(yīng)用里面打開(kāi)文件,那么可以通過(guò)第三方應(yīng)用打開(kāi)預(yù)覽文件。通過(guò)OptionsMenu(選項(xiàng)菜單),顯示能夠接收該類型文件的應(yīng)用,由用戶選擇相應(yīng)的操作。

顯示菜單可以使用下列方法:

- presentOptionsMenuFromRect:inView:animated:

- presentOptionsMenuFromBarButtonItem:animated:

- presentOpenInMenuFromRect:inView:animated:

- presentOpenInMenuFromBarButtonItem:animated:

這些方法都是類似的,只是顯示位置有區(qū)別而已。以下代碼演示其中一個(gè)方法的使用。

CGRect navRect = self.navigationController.navigationBar.frame;

navRect.size = CGSizeMake(1500.0f, 40.0f);

[documentController presentOptionsMenuFromRect:navRect

inView:self.view

animated:YES];

四、使用委托

如果你顯示一個(gè)Document Interaction Controller ,則必需要為delegate屬性用指定一個(gè)委托。讓委托告訴DocumentInteraction Controller如何顯示。

documentController.delegate = self;

委托對(duì)象需要實(shí)現(xiàn)一系列委托方法,最常見(jiàn)的包括:

- documentInteractionControllerViewControllerForPreview:

- documentInteractionControllerViewForPreview:

- documentInteractionControllerRectForPreview:

這3個(gè)方法在用戶點(diǎn)擊“快速查看”菜單時(shí)依次調(diào)用。

- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller {

return self;

}

- (UIView *)documentInteractionControllerViewForPreview:(UIDocumentInteractionController *)controller {

return self.view;

}

- (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController *)controller {

return self.view.frame;

}

//點(diǎn)擊預(yù)覽窗口的“Done”(完成)按鈕時(shí)調(diào)用

- (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)controller {

}

功能一:分享文件

- (void)shareFile {NSString*filePath = [[NSBundlemainBundle] pathForResource:@"皮卡丘"ofType:@"jpeg"];//創(chuàng)建實(shí)例UIDocumentInteractionController*documentController = [UIDocumentInteractionControllerinteractionControllerWithURL:[NSURLfileURLWithPath:filePath]];//設(shè)置代理documentController.delegate =self;BOOLcanOpen = [documentController presentOpenInMenuFromRect:CGRectZeroinView:self.view? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? animated:YES];if(!canOpen) {NSLog(@"沒(méi)有程序可以打開(kāi)要分享的文件");? ? }}

功能二:預(yù)覽文件(注冊(cè)應(yīng)用程序支持的文件類型)

- (void)preview {if(!_path) {return;? ? }NSURL*fileURL = [NSURLURLWithString:[NSStringstringWithFormat:@"%@%@", [selfgetURL], [_path lastPathComponent]]];//創(chuàng)建實(shí)例UIDocumentInteractionController*documentController =? ? [UIDocumentInteractionControllerinteractionControllerWithURL:fileURL];//設(shè)置代理documentController.delegate =self;? ? [documentController presentPreviewAnimated:YES];}

配置Info.plist文件

如果你的程序能夠打開(kāi)某種文件,你可以向系統(tǒng)進(jìn)行注冊(cè)。方便其他程序通過(guò) iOS 的document interaction技術(shù)提供給用戶一個(gè)選擇,從而調(diào)用你的程序處理這些文件。

這需要在程序的Info.plist文件中添加CFBundleDocumentTypes鍵(查看CoreFoundation Keys)。

系統(tǒng)將該鍵中包含的內(nèi)容進(jìn)行登記,這樣其他程序就可以通過(guò)document interaction controller訪問(wèn)到這些信息。

CFBundleDocumentTypes鍵是一個(gè)dictionary數(shù)組,每個(gè)dictionary表示了一個(gè)指定的文檔類型。一個(gè)文檔類型通常與某種文件類型是一一對(duì)應(yīng)的。

但是,如果你的程序?qū)Χ鄠€(gè)文件類型采用同樣的處理方式,你也可以把這些類型都分成一個(gè)組,統(tǒng)一視作一個(gè)文檔類型。例如,你的程序中使用到的本地文檔類型,有一個(gè)是舊格式的,還有一個(gè)新格式(似乎是影射微軟office文檔),則你可以將二者分成一組,都放到同一個(gè)文檔類型下。這樣,舊格式和新格式的文件都將顯示為同一個(gè)文檔類型,并以同樣的方式打開(kāi)。

CFBundleDocumentTypes數(shù)組中的每個(gè) dictionary 可能包含以下鍵:

CFBundleTypeName

指定文檔類型名稱。

CFBundleTypeIconFiles

是一個(gè)數(shù)組,包含多個(gè)圖片文件名,用于作為該文檔的圖標(biāo)。

LSItemContentTypes

是一個(gè)數(shù)組,包含多個(gè)UTI【Uniform Type Identifiers】類型的字符串。UTI類型是本文檔類型(組)所包含的文件類型。

LSHandlerRank

表示應(yīng)用程序是“擁有”還是僅僅是“打開(kāi)”這種類型而已。

下表列出了Info.plist中的一個(gè)CFBundleTypeName官方示例。

自定義文件格式的文檔類型

CFBundleTypeName

My File Format

CFBundleTypeIconFiles

MySmallIcon.png

MyLargeIcon.png

LSItemContentTypes

com.example.myformat

LSHandlerRank

Owner

自己程序配置文件

CFBundleDocumentTypes

CFBundleTypeName

com.myapp.common-data

LSItemContentTypes

com.microsoft.powerpoint.ppt

public.item

com.microsoft.word.doc

com.adobe.pdf

com.microsoft.excel.xls

public.image

public.content

public.composite-content

public.archive

public.audio

public.movie

public.text

public.data

打開(kāi)支持的文件類型

你可以在應(yīng)用程序委托的application:didFinishLaunchingWithOptions:方法中獲得該文件的信息。如果你的程序要處理某些自定義的文件類型,你必須實(shí)現(xiàn)這個(gè)委托方法(而不是applicationDidFinishLaunching: 方法) 并用這個(gè)方法啟動(dòng)應(yīng)用程序。

application:didFinishLaunchingWithOptions:方法的option參數(shù)包含了要打開(kāi)的文件的相關(guān)信息。尤其需要在程序中關(guān)心下列鍵:

UIApplicationLaunchOptionsURLKey

包含了該文件的NSURL。

UIApplicationLaunchOptionsSourceApplicationKey

包含了發(fā)送請(qǐng)求的應(yīng)用程序的 Bundle ID。

UIApplicationLaunchOptionsAnnotationKey

包含了源程序向目標(biāo)程序傳遞的與該文件相關(guān)的屬性列表對(duì)象。

如果UIApplicationLaunchOptionsURLKey鍵存在,你的程序應(yīng)當(dāng)立即用該 URL 打開(kāi)該文件并將內(nèi)容呈現(xiàn)給用戶。其他鍵可用于收集與打開(kāi)的文件相關(guān)的參數(shù)和信息。

如果你的應(yīng)用程序處于活躍狀態(tài),此時(shí)application:didFinishLaunchingWithOptions:方法是不會(huì)被調(diào)用的。需要實(shí)現(xiàn)application:openURL:options:方法

【以下是本人的寫(xiě)法】

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {? ? _vc = [[ViewController alloc] init];UINavigationController*nav? ? = [[UINavigationControlleralloc] initWithRootViewController:_vc];self.window? ? ? ? ? ? ? ? ? ? = [[UIWindowalloc] initWithFrame:[UIScreenmainScreen].bounds];self.window.backgroundColor? ? = [UIColorwhiteColor];self.window.rootViewController = nav;? ? [self.window makeKeyAndVisible];if(launchOptions) {NSString*str = [NSStringstringWithFormat:@"\n發(fā)送請(qǐng)求的應(yīng)用程序的 Bundle ID:%@\n\n文件的NSURL:%@\n\n文件相關(guān)的屬性列表對(duì)象:%@",? ? ? ? ? ? ? ? ? ? ? ? launchOptions[UIApplicationLaunchOptionsSourceApplicationKey],? ? ? ? ? ? ? ? ? ? ? ? launchOptions[UIApplicationLaunchOptionsURLKey],? ? ? ? ? ? ? ? ? ? ? ? launchOptions[UIApplicationLaunchOptionsSourceApplicationKey]];? ? ? ? [[[UIAlertViewalloc] initWithTitle:@""message:str? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? delegate:nilcancelButtonTitle:@"確定"otherButtonTitles:nil,nil] show];? ? ? ? _vc.path = [launchOptions[UIApplicationLaunchOptionsURLKey] description];? ? ? ? [_vc preview];? ? }returnYES;}- (BOOL)application:(UIApplication*)application openURL:(nonnullNSURL*)url options:(nonnullNSDictionary *)options {if(options) {NSString*str = [NSStringstringWithFormat:@"\n發(fā)送請(qǐng)求的應(yīng)用程序的 Bundle ID:%@\n\n文件的NSURL:%@", options[UIApplicationOpenURLOptionsSourceApplicationKey], url];? ? ? ? [[[UIAlertViewalloc] initWithTitle:@""message:str? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? delegate:nilcancelButtonTitle:@"確定"otherButtonTitles:nil,nil] show];? ? ? ? _vc.path = [url description];? ? ? ? [_vc preview];? ? }returnYES;}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容