iOS開發(fā) 打開另一個APP(URL Scheme與openURL)

目標

平常我們做iOS開發(fā)痊末,會經(jīng)常遇到打開其他的APP的功能绿饵。本篇文章講的就是打開別人的APP的一些知識捷凄。我們的目標是:

  • 打開別人的APP
  • 讓別人打開我們的APP
  • 版本大于等于iOS9的適配問題
  • 使用URL Schemes傳遞數(shù)據(jù)

準備工作

  • 建立一個名為OpenApp的工作空間,用來存放我們的兩個工程
    建立這個工作空間主要是為了讓我們后面建立的兩個工程能在一個Xcode頁面上管理虚汛,方便講解和管理匾浪。挺簡單的,不清楚的可以看我之前的文章【iOS開發(fā)】在一個Xcode頁面建立多個工程
image
  • 建立一個名為MyApp的iOS工程卷哩。這個MyApp是“我的app”蛋辈,用來打開另一個APP的。
    添加工程到我們剛才創(chuàng)建的OpenApp.xcworkspace殉疼。并且在工程的Main.storyboard添加一個button梯浪,待會兒我們會用來寫方法。

    image
  • 建立一個名為WXApp的iOS工程瓢娜。這個工程是我們模擬的“微信APP”挂洛,是被人打開的那個APP。
    為了區(qū)分兩個應用眠砾,我們在Main.storyboard上加一個label虏劲,“我是微信App”。

    image
image

好了褒颈,準備工作就這么簡單柒巫。

打開別人的APP與讓別人打開我們的APP

想要打開別人的APP或者讓別人打開我們的APP,那就需要通過URL Schemes了谷丸。

什么是URL Schemes堡掏?

URL Schemes是蘋果給出的用來跳轉到系統(tǒng)應用或者跳轉到別人的應用的一種機制。同時還可以在應用之間傳數(shù)據(jù)刨疼。

通過對比網(wǎng)頁鏈接來理解 iOS 上的 URL Schemes泉唁,應該就容易多了。
URL Schemes 有兩個單詞:

  • URL揩慕,我們都很清楚亭畜,http://www.apple.com
    就是個 URL,我們也叫它鏈接或網(wǎng)址迎卤;
  • Schemes拴鸵,表示的是一個 URL 中的一個位置——最初始的位置,即 ://
    之前的那段字符蜗搔。比如 http://www.apple.com
    這個網(wǎng)址的 Schemes是 http劲藐。
    根據(jù)我們上面對 URL Schemes 的使用,我們可以很輕易地理解樟凄,在以本地應用為主的 iOS 上瘩燥,我們可以像定位一個網(wǎng)頁一樣,用一種特殊的 URL 來定位一個應用甚至應用里某個具體的功能不同。而定位這個應用的厉膀,就應該是這個應用的 URL 的 Schemes 部分溶耘,也就是開頭兒那部分。

在WXApp上設置一個URL Schemes

為了能讓別的App(包括我們剛才創(chuàng)建的MyApp)能夠打開WXApp服鹅,我們需要為WXApp添加一個URL Schemes凳兵。
步驟:選中WXApp工程->Info->URL Types->點擊“+”->在URL Schemes欄填上 weixin

image

備注:一個應用是可以有多個URL Schemes的。你可以再次點擊“+”來添加一個URL Schemes

我們看看info.plist文件里面是怎樣的企软。

image

然后我們run一下WXApp庐扫。(注意一下你run的target是哪個)

image

這樣咙好,WXApp就向系統(tǒng)“注冊”了一個URL Schemes蜗字,其他的應用可以通過openurl:方法來打開WXApp了。

MyApp打開WXApp

現(xiàn)在我們在MyApp里面打開WXApp埋酬。方法非常簡單厌漂。
在ViewController里面添加一個方法

- (IBAction)openWXApp:(UIButton *)sender {
    [self demo1];
}
- (void)demo1 {
    //創(chuàng)建一個url萨醒,這個url就是WXApp的url,記得加上://
    NSURL *url = [NSURL URLWithString:@"weixin://"];

    //打開url
    [[UIApplication sharedApplication] openURL:url];
}

然后run一下MyApp

image

運行了之后點擊“打開微信”button苇倡,會彈出“MyApp”想要打開“WXApp”提示框富纸,點確認之后就可以跳轉到WXApp了。

image
image

iOS9之后旨椒,在一個應用跳轉到了另一個應用之后晓褪,左上角會有個返回到上一個應用的按鈕。這樣综慎,我們在MyApp里面點擊“打開微信”按鈕涣仿,跳轉到WXApp之后,再點擊“Back to MyApp”示惊,又回到MyApp了好港。閑著無聊就可以反復點擊這兩個按鈕來兩個應用間跳轉了,哈哈涝涤。

值得一說的是,這個URL Schemes并不是唯一的岛杀。也就是說阔拳,多個應用之間設置的URL Schemes是可以相同的。
那么問題來了类嗤,假如兩個應用的URL Schemes相同的話糊肠,使用openURL:方法會打開哪個應用呢?
樓主親自用手機試了一下遗锣。
步驟是:

  • 將MyApp安裝到手機上货裹,點擊“打開微信”button,微信打開了精偿。
  • 然后將WXApp也安裝到手機上弧圆。再次點擊MyApp的“打開微信”button赋兵,結果打開的是WXApp。
    結論:如果兩個應用有URL Schemes是相同的搔预,后安裝的應用的URL Schemes會把早安裝的應用的URL Schems覆蓋掉霹期。

20180528編輯:后安裝的應用的URL Schemes會把早安裝的應用的URL Schems覆蓋掉,這個結論是不合理的拯田。具體的話也沒測試出結果历造。就當留個坑吧。

在safari打開WXApp

沒錯船庇,注冊了URL Schemes的應用吭产,用safari瀏覽器也是可以打開的。我就經(jīng)常用這個來驗證應用是否設置了我想要的URL Schemes
在safari打開WXApp鸭轮,直接在safari的地址欄輸入weixin://,enter就可以打開了

image
image

版本大于等于iOS9的適配問題

  • 配置URL Schemes白名單
    其實在打開WXApp的時候臣淤,正常情況下,我們應該是先用canOpenURL:方法先判斷能否打開這個url张弛,然后再用openURL方法打開該URL的荒典。這樣可以帶來更好的用戶體驗。因為用戶不一定安裝了WXApp吞鸭。假如用戶沒有安裝的話點擊“打開微信”button是沒有任何反應的寺董。這時候我們應該先判斷是否能夠打開這個url(也就是判斷用戶有沒有安裝WXApp),沒有安裝的話就給個溫馨提示刻剥,比如:“U四不四灑遮咖,沒安裝WXApp,怎么打開霸炻病御吞!”。
    更重要的是漓藕,假如點擊之后沒效果陶珠,送審很有可能被蘋果拒絕哦。
- (IBAction)openWXApp:(UIButton *)sender {
//    [self demo1];
    [self demo2];
}
//先判斷再打開WXApp
- (void)demo2 {
    //創(chuàng)建一個url享钞,這個url就是WXApp的url揍诽,記得加上://
    NSURL *url = [NSURL URLWithString:@"weixin://"];

    //先判斷是否能打開該url
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        //打開url
        [[UIApplication sharedApplication] openURL:url];
    }else {
        //給個提示或者做點別的事情
        NSLog(@"U四不四灑,沒安裝WXApp栗竖,怎么打開笆畲唷!");
}

但是我們發(fā)現(xiàn)用了canOpenURL:方法之后狐肢,并沒有如我們想像中打開了WXApp添吗。一看,Xcode控制臺提示:

image

為什么會這樣呢份名?
因為iOS9的時候蘋果加強了權限碟联,只有在info.plist文件中加入了URL Schemes白名單才能使用canOpenURL:方法來判斷是否能打開該url妓美。該白名單的上限是50個。也就是說玄帕,你最多只能使用canOpenURL:方法判斷50個URL Schemes部脚。當然,平常我們都用不了那么多裤纹,就算是集成分享功能委刘,50個肯定夠了。

備注:只是對canOpenURL:方法有限制鹰椒,openURL:方法是沒有限制的锡移。

言歸正傳,我們需要在MyApp的info.plist里面將weixin設置為白名單漆际。
步驟:點擊info.plist->右鍵->Open As->Source Code->添加下面的代碼

    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>weixin</string>
    </array>

這樣就可以了淆珊。

使用URL Schems傳遞數(shù)據(jù)

URL Schemes除了可以用來打開APP之外,還可以用來在兩個App之間傳遞少量的數(shù)據(jù)奸汇。
在百度上搜索“ios”,會生成一個url施符,下面來以這個url來大概介紹url的組成。

url為:https://www.baidu.com/s?ie=UTF-8&wd=ios

  • https就是協(xié)議擂找,也就是scheme
  • www.baidu.com 是域名
  • /s是路徑
  • ?后面的是query戳吝,也就是查詢參數(shù)。這個url有兩個參數(shù)贯涎,分別是ie=UTF-8wd=ios

我們iOS的URL Schemes中也是差不多的听哭。
而且,在openURL的時候塘雳,如果url中帶有參數(shù)陆盘,只要URL Schemes是正確的,那同樣可以打開App败明,而且隘马,后面的參數(shù)也會帶到我們打開的App那里。
咱們做個Demo就一目了然了妻顶。
在MyApp中酸员,寫個demo3方法,url為weixin://www.shixueqian.com/abc?title=hello&content=helloworld

- (IBAction)openWXApp:(UIButton *)sender {
//    [self demo1];
//    [self demo2];
    [self demo3];
}
//使用URL Schemes傳遞數(shù)據(jù)
- (void)demo3 {
    //創(chuàng)建一個url,這個url就是WXApp的url盈包,記得加上://
    NSURL *url = [NSURL URLWithString:@"weixin://www.shixueqian.com/abc?title=hello&content=helloworld"];
    //打開url
    [[UIApplication sharedApplication] openURL:url];  
}

在WXApp的AppDelegate.m中沸呐,實現(xiàn)application: openURL:(NSURL *)url sourceApplication: annotation:回調

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {

    NSLog(@"url=====%@ \n  sourceApplication=======%@ \n  annotation======%@", url, sourceApplication, annotation);
    return YES;
}

run了之后醇王,我們發(fā)現(xiàn)呢燥,我們依舊可以通過點擊openURL:方法打開WXApp。而且在WXApp被打開的時候寓娩,會執(zhí)行application: openURL:(NSURL *)url sourceApplication: annotation:回調方法叛氨。在這個回調方法中呼渣,我們可以得到MyApp傳過來的url等信息。
控制臺打印如下:

image

完整的url信息都傳過來了寞埠,我們就可以利用這個url里面的路徑和參數(shù)等信息了屁置,想干嘛就干嘛。這就實現(xiàn)了從MyApp向WXApp傳遞數(shù)據(jù)了仁连。

備注:
蘋果一共給了3個openURL的回調蓝角。
分別是:

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url NS_DEPRECATED_IOS(2_0, 9_0, "Please use application:openURL:options:") __TVOS_PROHIBITED;
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation NS_DEPRECATED_IOS(4_2, 9_0, "Please use application:openURL:options:") __TVOS_PROHIBITED;
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options NS_AVAILABLE_IOS(9_0); // no equiv. notification. return NO if the application can't open for some reason

為什么會有3個呢?這3個回調又有什么區(qū)別饭冬?(為方面講解使鹅,分別設置ABC3個回調)

  • 3個回調的功能基本一樣,都是在別人通過URL Schemes打開應用的時候會執(zhí)行的昌抠。
    不同之處:
  • A回調是在iOS2.0的時候推出的患朱,參數(shù)只有url
  • B回到是在iOS4.2的時候推出的炊苫,參數(shù)有url sourceApplication annotation.
  • C回調是iOS9.0的時候推出的裁厅,參數(shù)有url optionsoptions有下面幾個key
// Keys for application:openURL:options:
UIKIT_EXTERN NSString *const UIApplicationOpenURLOptionsSourceApplicationKey NS_AVAILABLE_IOS(9_0);   // value is an NSString containing the bundle ID of the originating application
UIKIT_EXTERN NSString *const UIApplicationOpenURLOptionsAnnotationKey NS_AVAILABLE_IOS(9_0);   // value is a property-list typed object corresponding to what the originating application passed in UIDocumentInteractionController's annotation property
UIKIT_EXTERN NSString *const UIApplicationOpenURLOptionsOpenInPlaceKey NS_AVAILABLE_IOS(9_0);   // value is a bool NSNumber, set to YES if the file needs to be copied before use

  • 這幾個回調是有優(yōu)先級的侨艾。C>B>A执虹。也就是說,如果你3個回調都實現(xiàn)了蒋畜,那么程序只會執(zhí)行C回調声畏。其他回調是不會執(zhí)行的。(當然姻成,iOS9以下只會執(zhí)行B回調)插龄。

參考

本篇文章的Demo已經(jīng)上傳到GitHub上了https://github.com/shixueqian/OpenApp

歡迎觀看我的另一篇文章,是這篇文章的進階版科展。
【iOS開發(fā)】仿微信分享功能

謙言萬語

用通俗的語言均牢,講述動人的代碼故事。

作者:謙言忘語
鏈接:http://www.reibang.com/p/0811ccd6a65d
來源:簡書
著作權歸作者所有才睹。商業(yè)轉載請聯(lián)系作者獲得授權徘跪,非商業(yè)轉載請注明出處。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末琅攘,一起剝皮案震驚了整個濱河市垮庐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌坞琴,老刑警劉巖哨查,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異剧辐,居然都是意外死亡寒亥,警方通過查閱死者的電腦和手機邮府,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來溉奕,“玉大人褂傀,你說我怎么就攤上這事〖忧冢” “怎么了仙辟?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鳄梅。 經(jīng)常有香客問我欺嗤,道長,這世上最難降的妖魔是什么卫枝? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任煎饼,我火速辦了婚禮,結果婚禮上校赤,老公的妹妹穿的比我還像新娘吆玖。我一直安慰自己,他們只是感情好马篮,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布沾乘。 她就那樣靜靜地躺著,像睡著了一般浑测。 火紅的嫁衣襯著肌膚如雪翅阵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天迁央,我揣著相機與錄音掷匠,去河邊找鬼。 笑死岖圈,一個胖子當著我的面吹牛讹语,可吹牛的內容都是我干的。 我是一名探鬼主播蜂科,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼顽决,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了导匣?” 一聲冷哼從身側響起才菠,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贡定,沒想到半個月后赋访,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年进每,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片命斧。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡田晚,死狀恐怖,靈堂內的尸體忽然破棺而出国葬,到底是詐尸還是另有隱情贤徒,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布汇四,位于F島的核電站接奈,受9級特大地震影響,放射性物質發(fā)生泄漏通孽。R本人自食惡果不足惜序宦,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望背苦。 院中可真熱鬧互捌,春花似錦、人聲如沸行剂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽厚宰。三九已至腌巾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間铲觉,已是汗流浹背澈蝙。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留撵幽,地道東北人碉克。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像并齐,于是被迫代替她去往敵國和親漏麦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內容