iOS實(shí)現(xiàn)App之間的內(nèi)容分享

前言

我們?cè)趇OS平臺(tái)上想要實(shí)現(xiàn)不同App之間的內(nèi)容分享一般有幾種常用方式:

  1. 第一種是通過(guò)AirDrop實(shí)現(xiàn)不同設(shè)備的App之間文檔和數(shù)據(jù)的分享;
  2. 第二種是給每個(gè)App定義一個(gè)URL Scheme,通過(guò)訪問(wèn)指定了URL Scheme的一個(gè)URL,實(shí)現(xiàn)直接訪問(wèn)一個(gè)APP;
  3. 第三種是通過(guò)UIDocumentInteractionController或者是UIActivityViewController這倆個(gè)iOS SDK中封裝好的類在App之間發(fā)送數(shù)據(jù)、分享數(shù)據(jù)和操作數(shù)據(jù);
  4. 第四種是通過(guò)App Extension,在iOS 8的SDK中提供的擴(kuò)展新特性實(shí)現(xiàn)跨App的數(shù)據(jù)操作和分享;
  5. 還有一種集成第三方SDK實(shí)現(xiàn)的有限個(gè)App的數(shù)據(jù)分享,比如社交平臺(tái)(QQ,微信,新浪微博等)給我們提供的官方SDK,或者是集成了多個(gè)社交平臺(tái)的ShareSDK組件和友盟分享組件等。

關(guān)于集成第三方SDK的使用,各大平臺(tái)官網(wǎng)上都有詳細(xì)的文檔說(shuō)明,因此我們這系列文章主要是來(lái)談?wù)勌O(píng)果原生提供的基于iOS SDK的分享技術(shù),同時(shí)推薦倆篇蘋(píng)果開(kāi)發(fā)者中心的文檔:Inter-App CommunicationDocument Interaction Programming Topics for iOS。我們的第一篇文章就談一下如何通過(guò)UTI讓我們的App支持分享。

原理

我在“詳解蘋(píng)果提供的UTI(統(tǒng)一類型標(biāo)識(shí)符)“這篇文章中,詳細(xì)地講解了一下UTI(Uniform Type Identifier),一套蘋(píng)果給我們提供用來(lái)在基于Cocoa和Cocoa Touch應(yīng)用程序中識(shí)別實(shí)體內(nèi)容類型的規(guī)范,而關(guān)于實(shí)現(xiàn)內(nèi)容關(guān)聯(lián)的技術(shù)也正是基于這套規(guī)范。在iOS和Mac OS開(kāi)發(fā)中,蘋(píng)果給我們提供了注冊(cè)文檔類型的接口,而這種注冊(cè)的文檔類型是全局的,系統(tǒng)中所有的應(yīng)用程序和服務(wù)都可以偵測(cè)到。因此我們通過(guò)這個(gè)底層偵測(cè),可以使用其他可選的第三方App來(lái)預(yù)覽我們的App中不支持的文檔,而且我們還可以通過(guò)這個(gè)接口在我們的App中打開(kāi)并處理第三方App的文檔。

如果我們的App可以處理某些類型的實(shí)體內(nèi)容,那么我們就可以在我們項(xiàng)目中的Info.plist文件中進(jìn)行注冊(cè)。關(guān)于使用哪種類型和UTI,就要參考我在“詳解蘋(píng)果提供的UTI(統(tǒng)一類型標(biāo)識(shí)符)“這篇文章中的講解。當(dāng)一個(gè)第三方App通過(guò)蘋(píng)果的底層偵測(cè)技術(shù)檢查有哪些App可以處理它所指定的內(nèi)容類型時(shí),如果我們的App已經(jīng)注冊(cè)了這種類型,那么我們的App圖標(biāo)就會(huì)顯示在其中,并且作為我們自己的App的一個(gè)入口。

主要技術(shù)

主要應(yīng)用到這種底層偵測(cè)的技術(shù)有iOS SDK中給我們提供的UIDocumentInteractionControllerUIActivityViewControllerQuick Look 框架。此外,在iOS 8中,蘋(píng)果又給開(kāi)發(fā)者提供了App Extension,一種更高大上的方式在App之間的實(shí)現(xiàn)分享內(nèi)容。關(guān)于UIDocumentInteractionControllerUIActivityViewControllerQuick Look 框架以及App Extension的細(xì)節(jié),我計(jì)劃在后面的文章中詳細(xì)講解。這篇文章,我們主要是來(lái)談?wù)?code>如何注冊(cè)我們App可用的文檔類型以及簡(jiǎn)單使用我們的App來(lái)處理第三方App分享的內(nèi)容

注冊(cè)可用類型

我們需要在info.plist文件中,添加一個(gè)新的屬性CFBundleDocumentTypes(實(shí)際上輸入的是"Document types"),這是一個(gè)數(shù)組類型的屬性,意思就是我們可以同時(shí)注冊(cè)多個(gè)類型。而針對(duì)數(shù)組中的每一個(gè)元素,都有許多屬性可以指定,詳細(xì)的屬性列表我們可以從官方文檔上找到: Core Foundation Keys ---- CFBundleDocumentTypes。這里列舉我們?cè)谧鰅OS開(kāi)發(fā)時(shí)常用的屬性:

  • CFBundleTypeName("Icon File Name")
    字符串類型,指定某種類型的別名,也就是用來(lái)指代我們規(guī)定的類型的別稱,一般為了保持唯一性,我們使用UTI來(lái)標(biāo)識(shí)。
  • CFBundleTypeIconFiles
    數(shù)組類型,包含指定的png圖標(biāo)的文件名,指定代表某種類型的圖標(biāo),而圖標(biāo)有具體的尺寸標(biāo)識(shí):

|Device |Sizes |
|:------|:---------|
|iPad |64 x 64 pixels, 320 x 320 pixels|
|iPhone and iPod touch|22 x 29 pixels, 44 x 58 pixels (high resolution)|

  • LSItemContentTypes("Document Content Type UTIs")
    數(shù)組類型,包含UTI字符串,指定我們的應(yīng)用程序所有可以識(shí)別的類型集合
  • LSHandlerRank("Handler rank")
    字符串類型,包含Owner,Default,Alternate,None四個(gè)可選值,指定對(duì)于某種類型的優(yōu)先權(quán)級(jí)別,而Launcher Service會(huì)根據(jù)這個(gè)優(yōu)先級(jí)別來(lái)排列顯示的App的順序。優(yōu)先級(jí)別從高到低依次是OwnerAlternate,DefaultNone表示不接受這種類型。

了解了這些基本屬性,我們就需要在注冊(cè)App可用類型時(shí),指定這些屬性,根據(jù)每個(gè)項(xiàng)目的需求不同,屬性值也不同。具體的注冊(cè)請(qǐng)參照我的GitHub上的項(xiàng)目:SeraZheng---ZSUTITest。下圖示例作為一個(gè)參照:

在info中添加Document types

而當(dāng)我們添加完所有屬性后,開(kāi)始運(yùn)行我們的程序,然后再回到我們的Info界面,就會(huì)看到Document types這個(gè)列表已經(jīng)發(fā)生了變化,這就證明我們成功的注冊(cè)好了App可用的類型。

注冊(cè)成功,運(yùn)行程序顯示的結(jié)果

打開(kāi)第三方應(yīng)用

我們?cè)谏厦娴牟襟E中注冊(cè)好了我們的App可以識(shí)別的類型,現(xiàn)在我們可以打開(kāi)一個(gè)使用UIDocumentInteractionController或者是Quick Look框架來(lái)展示內(nèi)容的第三方App,這里以iPhone 上的QQ程序?yàn)槔?/p>

我們?cè)谏厦娴淖?cè)步驟中,注冊(cè)的LSItemContentTypes僅包含了public.image這個(gè)UTI。所以我們先從QQ應(yīng)用程序的我的文件中,打開(kāi)不同類型的文件進(jìn)行對(duì)比,大家可以看下圖我的文件列表中包含倆種類型的文件,一種是.jpg擴(kuò)展名的圖片文件,一種是.pdf擴(kuò)展名的文檔文件。

我的文件列表

當(dāng)我打開(kāi)一個(gè)圖片文件進(jìn)行預(yù)覽時(shí),點(diǎn)擊其他應(yīng)用打開(kāi),就可以在App列表中看到我們的App圖標(biāo)。簡(jiǎn)單介紹一下這個(gè)頁(yè)面,第一行是蘋(píng)果在iOS 7之后給我們提供的使用AirDropiPhoneiPadiPod Touch設(shè)備之間通過(guò)iCloud共享內(nèi)容的一種方式。第二行是通過(guò)文檔類型關(guān)聯(lián)技術(shù)識(shí)別的App的列表。第三行是通過(guò)文檔關(guān)聯(lián)技術(shù)識(shí)別的Action的列表,Action表示對(duì)文檔可進(jìn)行的操作,如復(fù)制,打印等。

打開(kāi)圖片,顯示ZSUTITestDemo App圖標(biāo)

而如果我打開(kāi)PDF文件的話,就看不到我們的App圖標(biāo)。


打開(kāi)PDF文件,看不到ZSUTITestDemo App圖標(biāo)

程序回調(diào)

當(dāng)我們通過(guò)上面步驟,成功地顯示了ZSUTITestDemo 的圖標(biāo)之后,點(diǎn)擊圖標(biāo),我們就可以跳轉(zhuǎn)到ZSUTITestDemo應(yīng)用中,而蘋(píng)果在iOS SDK中給我們提供的接收回調(diào)的方法在iOS 9之后做出了改變,因此我們需要針對(duì)不同的設(shè)備版本做出改變:

#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation
{
    UINavigationController *navigation = (UINavigationController *)application.keyWindow.rootViewController;
    ViewController *displayController = (ViewController *)navigation.topViewController;
    
    [displayController.imageView setImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:url]]];
    [displayController.label setText:sourceApplication];
    
    return YES;
}

#else
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(nonnull NSDictionary<NSString *,id> *)options
{
    UINavigationController *navigation = (UINavigationController *)application.keyWindow.rootViewController;
    ViewController *displayController = (ViewController *)navigation.topViewController;
    
    [displayController.imageView setImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:url]]];
    [displayController.label setText:[options objectForKey:UIApplicationOpenURLOptionsSourceApplicationKey]];
    
    return YES;
}
#endif

Demo示例可以從GitHub項(xiàng)目上參照代碼:SeraZheng---ZSUTITest。當(dāng)點(diǎn)擊ZSUTITestDemo程序圖標(biāo)回到調(diào)用代碼中,我們可以在這里做各種我們想做的事,如上傳圖片、預(yù)覽圖片、操作圖片等等。我只對(duì)圖片做了簡(jiǎn)單的預(yù)覽顯示,然后顯示文件的源程序的Bundle Identifier,示例如下圖:

顯示圖片和源程序的Bundle Identifier
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評(píng)論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,556評(píng)論 3 418
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,463評(píng)論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,009評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,778評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,218評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,436評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,969評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,795評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,993評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,229評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,659評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,917評(píng)論 1 286
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,687評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,990評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容