UIDocumentInteractionController和UIActivityViewController主要都是用來完成app間文件傳輸?shù)墓δ埽ㄒ簿褪莻髡f中的進(jìn)程間交互),很多人將他當(dāng)做是一種系統(tǒng)原生的分享方案。具體如何實(shí)現(xiàn)在此就不做贅述了,很多前輩都寫過相關(guān)的文章,非常詳盡。
這篇文章主要解決的問題是:
通過UIDocumentInteractionController/UIActivityViewController把文件分享給第三方app,之前本來用的好好的,怎么到了iOS11就毫無反應(yīng)了呢?
解決問題的關(guān)鍵點(diǎn)就是:copy文件到沙盒。
對,就是這么簡單,但也就是這么出人意料。實(shí)際應(yīng)用中,大多數(shù)分享的文件可能都是保存在沙盒里的;但是,一般做Demo的時(shí)候,大多可能就是拖個(gè)文件到boundle中,這也就造成了后續(xù)分享文件功能毫無反應(yīng)的結(jié)果。
來說說具體怎么改進(jìn)吧。
- 首先,如果你要分享的文件是在boundle中,那么就一定要先把他copy到沙盒中,然后把沙盒路徑傳給UIDocumentInteractionController/UIActivityViewController;
- 既然做了copy,那么大多數(shù)情況下也同樣需要remove掉,不然應(yīng)用所占體積會(huì)越來越大,當(dāng)然,如果你有特殊需求除外。但是remove需要放在哪里進(jìn)行呢?
1 - 對UIActivityViewController 來說,他有一個(gè)屬性completionWithItemsHandler,這是用戶完成/取消選擇的回調(diào),在回調(diào)中刪除沙盒中copy過去的文件,并不影響三方app獲取文件,因?yàn)榇藭r(shí)文件已經(jīng)被復(fù)制到了三方的沙盒中,默認(rèn)是/Documents/Inbox中。
2 - 對于UIDocumentInteractionController,其分享彈窗有兩套方法:OpenInMenu 和 OptionsMenu,甚至連代理方法都有對應(yīng)的兩套:
- (void)documentInteractionControllerDidDismissOptionsMenu:(UIDocumentInteractionController *)controller;
- (void)documentInteractionControllerDidDismissOpenInMenu:(UIDocumentInteractionController *)controller;
從方法名就可以看出來,這兩個(gè)方法也是分享彈窗在消失時(shí)調(diào)用的代理方法,因此根據(jù)你彈出分享彈窗的方式在相應(yīng)的代理方法中實(shí)現(xiàn)remove文件的操作即可。
- 如果你的app需要接收別人分享過來的文件,那么在什么地方接收呢?
在UIDocumentInteractionController的官方文檔《Document Interaction Programming Topics for iOS》中
You receive information about the file to be opened in the
application:willFinishLaunchingWithOptions:orapplication:didFinishLaunchingWithOptions:method of your application delegate. If your application handles custom file types, you must implement this delegate method (instead of theapplicationDidFinishLaunching:method) and use it to initialize your application.
建議使用application:willFinishLaunchingWithOptions:或application:didFinishLaunchingWithOptions:方法來接收分享過來的文件信息,但經(jīng)過我的實(shí)踐發(fā)現(xiàn):
無論iOS11還是iOS10,無論是UIDocumentInteractionController還是UIActivityViewController:
1.當(dāng)接收app在后臺(tái)時(shí),有其他app向其分享文件,都會(huì)執(zhí)行
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options方法;
2.接收app在完全退出的情況下,有其他app向其分享文件,會(huì)先后執(zhí)行
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
和
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法。
因此個(gè)人建議統(tǒng)一在openURL方法中處理即可。
還有一個(gè)很坑的地方,就是UIDocumentInteractionController的強(qiáng)引用問題。在iOS11之前,如果不強(qiáng)引用,則會(huì)直接崩潰;而在iOS11中,不崩潰了~ 我原本天真的以為,是修好了~然而我還是太年輕。。。僅僅只是把崩潰修好了而已?。。∧憧赡軟]太理解我的意思吧?崩潰修好了不就是好了嗎?是“只”有崩潰好了!后面的功能還是不能用!還得強(qiáng)引用才能正常使用!我勒個(gè)擦!以前還有報(bào)錯(cuò)信息可循,現(xiàn)在直接就是毫無反應(yīng),讓人更加懵圈!簡直爆炸?。。?!
還有就是這個(gè)copy文件的問題,我也沒有在任何官方文檔中看到,因?yàn)閕OS11出來之后,和UIDocumentInteractionController還有UIActivityViewController相關(guān)的所有文檔,Guide,Sample Code等等都沒有過任何更新。。。感覺又是Apple自己悄悄弄的呢。。。(如果有小伙伴能找到相關(guān)的官方說明,敬請賜教,非常感謝!)
特別鳴謝
我全網(wǎng)只在這個(gè)帖子的9樓看到了copy的解決方法(他說的是copy到cache中,實(shí)測到Document也沒有問題),鳴謝這位做好事不留名的英雄。