目標(biāo)
平常我們做iOS開發(fā)盾沫,會(huì)經(jīng)常遇到打開其他的APP的功能哩牍。本篇文章講的就是打開別人的APP的一些知識(shí)棚潦。我們的目標(biāo)是:
- 打開別人的APP
- 讓別人打開我們的APP
- 版本大于等于iOS9的適配問題
- 使用URL Schemes傳遞數(shù)據(jù)
準(zhǔn)備工作
- 建立一個(gè)名為OpenApp的工作空間,用來存放我們的兩個(gè)工程
建立這個(gè)工作空間主要是為了讓我們后面建立的兩個(gè)工程能在一個(gè)Xcode頁面上管理膝昆,方便講解和管理。挺簡單的叠必,不清楚的可以看我之前的文章【iOS開發(fā)】在一個(gè)Xcode頁面建立多個(gè)工程
-
建立一個(gè)名為MyApp的iOS工程荚孵。這個(gè)MyApp是“我的app”,用來打開另一個(gè)APP的纬朝。
添加工程到我們剛才創(chuàng)建的OpenApp.xcworkspace收叶。并且在工程的Main.storyboard添加一個(gè)button,待會(huì)兒我們會(huì)用來寫方法共苛。
MyApp工程 -
建立一個(gè)名為WXApp的iOS工程判没。這個(gè)工程是我們模擬的“微信APP”,是被人打開的那個(gè)APP隅茎。
為了區(qū)分兩個(gè)應(yīng)用澄峰,我們?cè)贛ain.storyboard上加一個(gè)label,“我是微信App”辟犀。
在workspace建立WXApp工程
好了俏竞,準(zhǔn)備工作就這么簡單。
打開別人的APP與讓別人打開我們的APP
想要打開別人的APP或者讓別人打開我們的APP堂竟,那就需要通過URL Schemes了魂毁。
什么是URL Schemes?
URL Schemes是蘋果給出的用來跳轉(zhuǎn)到系統(tǒng)應(yīng)用或者跳轉(zhuǎn)到別人的應(yīng)用的一種機(jī)制出嘹。同時(shí)還可以在應(yīng)用之間傳數(shù)據(jù)席楚。
通過對(duì)比網(wǎng)頁鏈接來理解 iOS 上的 URL Schemes,應(yīng)該就容易多了税稼。
URL Schemes 有兩個(gè)單詞:
- URL烦秩,我們都很清楚垮斯,http://www.apple.com
就是個(gè) URL,我們也叫它鏈接或網(wǎng)址闻镶;- Schemes甚脉,表示的是一個(gè) URL 中的一個(gè)位置——最初始的位置,即 ://
之前的那段字符铆农。比如 http://www.apple.com
這個(gè)網(wǎng)址的 Schemes是 http牺氨。
根據(jù)我們上面對(duì) URL Schemes 的使用,我們可以很輕易地理解墩剖,在以本地應(yīng)用為主的 iOS 上猴凹,我們可以像定位一個(gè)網(wǎng)頁一樣,用一種特殊的 URL 來定位一個(gè)應(yīng)用甚至應(yīng)用里某個(gè)具體的功能岭皂。而定位這個(gè)應(yīng)用的郊霎,就應(yīng)該是這個(gè)應(yīng)用的 URL 的 Schemes 部分,也就是開頭兒那部分爷绘。
在WXApp上設(shè)置一個(gè)URL Schemes
為了能讓別的App(包括我們剛才創(chuàng)建的MyApp)能夠打開WXApp书劝,我們需要為WXApp添加一個(gè)URL Schemes。
步驟:選中WXApp工程->Info->URL Types->點(diǎn)擊“+”->在URL Schemes欄填上 weixin
備注:一個(gè)應(yīng)用是可以有多個(gè)URL Schemes的土至。你可以再次點(diǎn)擊“+”來添加一個(gè)URL Schemes
我們看看info.plist文件里面是怎樣的购对。
然后我們r(jià)un一下WXApp。(注意一下你run的target是哪個(gè))
這樣陶因,WXApp就向系統(tǒng)“注冊(cè)”了一個(gè)URL Schemes骡苞,其他的應(yīng)用可以通過openurl:
方法來打開WXApp了。
MyApp打開WXApp
現(xiàn)在我們?cè)贛yApp里面打開WXApp楷扬。方法非常簡單解幽。
在ViewController里面添加一個(gè)方法
- (IBAction)openWXApp:(UIButton *)sender {
[self demo1];
}
- (void)demo1 {
//創(chuàng)建一個(gè)url,這個(gè)url就是WXApp的url烘苹,記得加上://
NSURL *url = [NSURL URLWithString:@"weixin://"];
//打開url
[[UIApplication sharedApplication] openURL:url];
}
然后run一下MyApp
運(yùn)行了之后點(diǎn)擊“打開微信”button躲株,會(huì)彈出“MyApp”想要打開“WXApp”
提示框,點(diǎn)確認(rèn)之后就可以跳轉(zhuǎn)到WXApp了螟加。
iOS9之后徘溢,在一個(gè)應(yīng)用跳轉(zhuǎn)到了另一個(gè)應(yīng)用之后,左上角會(huì)有個(gè)返回到上一個(gè)應(yīng)用的按鈕捆探。這樣然爆,我們?cè)贛yApp里面點(diǎn)擊“打開微信”按鈕,跳轉(zhuǎn)到WXApp之后黍图,再點(diǎn)擊“Back to MyApp”曾雕,又回到MyApp了。閑著無聊就可以反復(fù)點(diǎn)擊這兩個(gè)按鈕來兩個(gè)應(yīng)用間跳轉(zhuǎn)了助被,哈哈剖张。
值得一說的是切诀,這個(gè)URL Schemes并不是唯一的。也就是說搔弄,多個(gè)應(yīng)用之間設(shè)置的URL Schemes是可以相同的幅虑。
那么問題來了,假如兩個(gè)應(yīng)用的URL Schemes相同的話顾犹,使用openURL:
方法會(huì)打開哪個(gè)應(yīng)用呢倒庵?
樓主親自用手機(jī)試了一下。
步驟是:
- 將MyApp安裝到手機(jī)上炫刷,點(diǎn)擊“打開微信”button擎宝,微信打開了。
- 然后將WXApp也安裝到手機(jī)上浑玛。再次點(diǎn)擊MyApp的“打開微信”button绍申,結(jié)果打開的是WXApp。
結(jié)論:如果兩個(gè)應(yīng)用有URL Schemes是相同的顾彰,后安裝的應(yīng)用的URL Schemes會(huì)把早安裝的應(yīng)用的URL Schems覆蓋掉极阅。
20180528編輯:
后安裝的應(yīng)用的URL Schemes會(huì)把早安裝的應(yīng)用的URL Schems覆蓋掉
,這個(gè)結(jié)論是不合理的涨享。具體的話也沒測(cè)試出結(jié)果涂屁。就當(dāng)留個(gè)坑吧。
在safari打開WXApp
沒錯(cuò)灰伟,注冊(cè)了URL Schemes的應(yīng)用,用safari瀏覽器也是可以打開的儒旬。我就經(jīng)常用這個(gè)來驗(yàn)證應(yīng)用是否設(shè)置了我想要的URL Schemes
在safari打開WXApp栏账,直接在safari的地址欄輸入weixin://
,enter就可以打開了
版本大于等于iOS9的適配問題
- 配置URL Schemes白名單
其實(shí)在打開WXApp的時(shí)候,正常情況下栈源,我們應(yīng)該是先用canOpenURL:
方法先判斷能否打開這個(gè)url挡爵,然后再用openURL
方法打開該URL的。這樣可以帶來更好的用戶體驗(yàn)甚垦。因?yàn)橛脩舨灰欢ò惭b了WXApp茶鹃。假如用戶沒有安裝的話點(diǎn)擊“打開微信”button是沒有任何反應(yīng)的。這時(shí)候我們應(yīng)該先判斷是否能夠打開這個(gè)url(也就是判斷用戶有沒有安裝WXApp)艰亮,沒有安裝的話就給個(gè)溫馨提示闭翩,比如:“U四不四灑,沒安裝WXApp迄埃,怎么打開傲圃稀!”侄非。
更重要的是蕉汪,假如點(diǎn)擊之后沒效果流译,送審很有可能被蘋果拒絕哦。
- (IBAction)openWXApp:(UIButton *)sender {
// [self demo1];
[self demo2];
}
//先判斷再打開WXApp
- (void)demo2 {
//創(chuàng)建一個(gè)url者疤,這個(gè)url就是WXApp的url福澡,記得加上://
NSURL *url = [NSURL URLWithString:@"weixin://"];
//先判斷是否能打開該url
if ([[UIApplication sharedApplication] canOpenURL:url]) {
//打開url
[[UIApplication sharedApplication] openURL:url];
}else {
//給個(gè)提示或者做點(diǎn)別的事情
NSLog(@"U四不四灑,沒安裝WXApp驹马,怎么打開案镌摇!");
}
但是我們發(fā)現(xiàn)用了canOpenURL:
方法之后窥翩,并沒有如我們想像中打開了WXApp业岁。一看,Xcode控制臺(tái)提示:
為什么會(huì)這樣呢寇蚊?
因?yàn)閕OS9的時(shí)候蘋果加強(qiáng)了權(quán)限笔时,只有在info.plist文件中加入了URL Schemes白名單才能使用canOpenURL:
方法來判斷是否能打開該url。該白名單的上限是50個(gè)仗岸。也就是說允耿,你最多只能使用canOpenURL:
方法判斷50個(gè)URL Schemes。當(dāng)然扒怖,平常我們都用不了那么多较锡,就算是集成分享功能,50個(gè)肯定夠了盗痒。
備注:只是對(duì)
canOpenURL:
方法有限制蚂蕴,openURL:
方法是沒有限制的。
言歸正傳俯邓,我們需要在MyApp的info.plist里面將weixin
設(shè)置為白名單骡楼。
步驟:點(diǎn)擊info.plist->右鍵->Open As->Source Code->添加下面的代碼
<key>LSApplicationQueriesSchemes</key>
<array>
<string>weixin</string>
</array>
這樣就可以了。
使用URL Schems傳遞數(shù)據(jù)
URL Schemes除了可以用來打開APP之外稽鞭,還可以用來在兩個(gè)App之間傳遞少量的數(shù)據(jù)鸟整。
在百度上搜索“ios”,會(huì)生成一個(gè)url,下面來以這個(gè)url來大概介紹url的組成朦蕴。
url為:https://www.baidu.com/s?ie=UTF-8&wd=ios
- https就是協(xié)議篮条,也就是scheme
- www.baidu.com 是域名
- /s是路徑
- ?后面的是query,也就是查詢參數(shù)吩抓。這個(gè)url有兩個(gè)參數(shù)涉茧,分別是
ie=UTF-8
和wd=ios
我們iOS的URL Schemes中也是差不多的。
而且琴拧,在openURL
的時(shí)候降瞳,如果url中帶有參數(shù),只要URL Schemes是正確的,那同樣可以打開App挣饥,而且除师,后面的參數(shù)也會(huì)帶到我們打開的App那里。
咱們做個(gè)Demo就一目了然了扔枫。
在MyApp中汛聚,寫個(gè)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)建一個(gè)url,這個(gè)url就是WXApp的url短荐,記得加上://
NSURL *url = [NSURL URLWithString:@"weixin://www.shixueqian.com/abc?title=hello&content=helloworld"];
//打開url
[[UIApplication sharedApplication] openURL:url];
}
在WXApp的AppDelegate.m中倚舀,實(shí)現(xiàn)application: openURL:(NSURL *)url sourceApplication: annotation:
回調(diào)
- (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)忍宋,我們依舊可以通過點(diǎn)擊openURL:
方法打開WXApp痕貌。而且在WXApp被打開的時(shí)候,會(huì)執(zhí)行application: openURL:(NSURL *)url sourceApplication: annotation:
回調(diào)方法糠排。在這個(gè)回調(diào)方法中舵稠,我們可以得到MyApp傳過來的url等信息。
控制臺(tái)打印如下:
完整的url信息都傳過來了入宦,我們就可以利用這個(gè)url里面的路徑和參數(shù)等信息了哺徊,想干嘛就干嘛。這就實(shí)現(xiàn)了從MyApp向WXApp傳遞數(shù)據(jù)了乾闰。
備注:
蘋果一共給了3個(gè)openURL的回調(diào)落追。
分別是:- (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
為什么會(huì)有3個(gè)呢?這3個(gè)回調(diào)又有什么區(qū)別涯肩?(為方面講解轿钠,分別設(shè)置ABC3個(gè)回調(diào))
- 3個(gè)回調(diào)的功能基本一樣,都是在別人通過URL Schemes打開應(yīng)用的時(shí)候會(huì)執(zhí)行的病苗。
不同之處: - A回調(diào)是在iOS2.0的時(shí)候推出的谣膳,參數(shù)只有
url
。 - B回到是在iOS4.2的時(shí)候推出的铅乡,參數(shù)有
url
sourceApplication
annotation
. - C回調(diào)是iOS9.0的時(shí)候推出的,參數(shù)有
url
options
烈菌。options
有下面幾個(gè)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
- 這幾個(gè)回調(diào)是有優(yōu)先級(jí)的阵幸。C>B>A。也就是說芽世,如果你3個(gè)回調(diào)都實(shí)現(xiàn)了挚赊,那么程序只會(huì)執(zhí)行C回調(diào)。其他回調(diào)是不會(huì)執(zhí)行的济瓢。(當(dāng)然荠割,iOS9以下只會(huì)執(zhí)行B回調(diào))。
參考
本篇文章的Demo已經(jīng)上傳到GitHub上了https://github.com/shixueqian/OpenApp
歡迎觀看我的另一篇文章,是這篇文章的進(jìn)階版蔑鹦。
【iOS開發(fā)】仿微信分享功能
謙言萬語
用通俗的語言夺克,講述動(dòng)人的代碼故事。