資料來(lái)源 & Demo
CocoaChina 一個(gè)強(qiáng)大的學(xué)習(xí)網(wǎng)址1跋А@崮琛!
1. 應(yīng)用間相互跳轉(zhuǎn)簡(jiǎn)介
在 iOS 開(kāi)發(fā)的過(guò)程中誓篱,我們經(jīng)常會(huì)遇到需要從一個(gè) 應(yīng)用程序A 跳轉(zhuǎn)到另一個(gè) 應(yīng)用程序B 的場(chǎng)景。這就需要我們掌握 iOS 應(yīng)用程序之間的相互跳轉(zhuǎn)知識(shí)凯楔。
2. 應(yīng)用間相互跳轉(zhuǎn)應(yīng)用場(chǎng)景
使用第三方用戶登錄窜骄,跳轉(zhuǎn)到需授權(quán)的App。如QQ登錄摆屯,微信登錄等邻遏。
需要用戶授權(quán),還需要"返回到調(diào)用的程序虐骑,同時(shí)返回授權(quán)的用戶名准验、密碼"。
應(yīng)用程序推廣廷没,跳轉(zhuǎn)到另一個(gè)應(yīng)用程序(本機(jī)已經(jīng)安裝)糊饱,或者跳轉(zhuǎn)到 iTunes 并顯示應(yīng)用程序下載頁(yè)面(本機(jī)沒(méi)有安裝)。
第三方支付颠黎,跳轉(zhuǎn)到第三方支付App另锋,如支付寶支付,微信支付盏缤。
內(nèi)容分享砰蠢,跳轉(zhuǎn)到分享App的對(duì)應(yīng)頁(yè)面,如分享給微信好友唉铜、分享給微信朋友圈台舱、分享到微博。
顯示位置、地圖導(dǎo)航竞惋,跳轉(zhuǎn)到地圖應(yīng)用柜去。
使用系統(tǒng)內(nèi)置程序,跳轉(zhuǎn)到打電話拆宛、發(fā)短信嗓奢、發(fā)郵件、Safari打開(kāi)網(wǎng)頁(yè)等內(nèi)置App中浑厚。
3. 應(yīng)用間相互跳轉(zhuǎn)實(shí)現(xiàn)原理
在 iOS 中打開(kāi)一個(gè)應(yīng)用程序只需要拿到這個(gè)應(yīng)用程序的 ** 協(xié)議頭 ** 即可睦裳,所以我們只需配置應(yīng)用程序的協(xié)議頭即可二庵。
假設(shè)有 應(yīng)用A 和 應(yīng)用B 兩個(gè)應(yīng)用缸血,現(xiàn)在需要從 應(yīng)用A 跳轉(zhuǎn)到 應(yīng)用B 中澜汤。
原理: 通過(guò)設(shè)置跳轉(zhuǎn)到應(yīng)用B的URL Schemes(自定義的協(xié)議頭),應(yīng)用B將其自身“綁定”到一個(gè)自定義 URL Schemes 上敢艰,就可以從 應(yīng)用A 中利用 應(yīng)用B 的 URL Schemes 啟動(dòng)應(yīng)用B了诬乞。
4. 應(yīng)用A跳轉(zhuǎn)到應(yīng)用B
1、首先我們用Xcode創(chuàng)建兩個(gè)iOS應(yīng)用程序項(xiàng)目钠导,項(xiàng)目名稱分別為AppA震嫉、AppB。
2牡属、選擇項(xiàng)目AppB -> TARGETS -> Info -> URL Types -> URL Schemes票堵,設(shè)置AppB的URL Schemes為 AppB。
3湃望、在應(yīng)用程序App-A中添加一個(gè)用來(lái)點(diǎn)擊跳轉(zhuǎn)的Button换衬,并監(jiān)聽(tīng)點(diǎn)擊事件,添加跳轉(zhuǎn)代碼证芭。
相關(guān)代碼
- (IBAction)jumbToAPPB:(id)sender {
// 1、獲取應(yīng)用程序APPB 的 URL Scheme
NSURL *appBUrl = [NSURL URLWithString:@"APPB://"];
// 2担映、判斷手機(jī)中是否安裝了對(duì)應(yīng)的程序
if ([[UIApplication sharedApplication] canOpenURL:appBUrl]) {
// 3废士、打開(kāi)應(yīng)用程序 APPB
[[UIApplication sharedApplication] openURL:appBUrl options:@{} completionHandler:nil];
} else {
NSLog(@"沒(méi)有安裝");
}
}
4、如果是 iOS 9 之前的模擬器或是真機(jī)蝇完,那么在相同的模擬器中先后運(yùn)行 AppB官硝、AppA,點(diǎn)擊按鈕短蜕,就可以實(shí)現(xiàn)跳轉(zhuǎn)了氢架。
5、如果是 iOS 9 之后的模擬器或是真機(jī)朋魔,那么則需要再在應(yīng)用程序 AppA 中將 AppB 的 URL Schemes 添加到白名單中岖研,原因和做法如下:
iOS 9 引入了白名單的概念。
在 iOS 9 中,如果使用 canOpenURL: 方法孙援,該方法所涉及到的 URL Schemes 必須在"Info.plist"中將它們列為白名單害淤,否則不能使用。key叫做LSApplicationQueriesSchemes 拓售,鍵值內(nèi)容是對(duì)應(yīng)應(yīng)用程序的 URL Schemes窥摄。
具體做法就是在 AppA 的 Info 文件中,添加 LSApplicationQueriesSchemes 數(shù)組础淤,然后添加鍵值為 AppB 的字符串崭放。
添加 LSApplicationQueriesSchemes 數(shù)組,然后添加鍵值為 AppB 的字符串
添加白名單之后在相同的模擬器中先后運(yùn)行 AppB鸽凶、AppA莹菱,點(diǎn)擊按鈕,就可以實(shí)現(xiàn)跳轉(zhuǎn)了吱瘩。
具體效果如下圖所示道伟。
5. 應(yīng)用A 跳轉(zhuǎn)到 應(yīng)用B 的特定界面
很多時(shí)候,我們做應(yīng)用程序之間的跳轉(zhuǎn)并不只是跳轉(zhuǎn)到其他程序就可以了使碾,而是要跳轉(zhuǎn)到其他程序的特定頁(yè)面上蜜徽。比如我們?cè)跒g覽網(wǎng)頁(yè)時(shí),會(huì)有分享到微信朋友圈或是分享給微信朋友票摇,這就需要跳轉(zhuǎn)到微信朋友圈界面或是微信朋友選擇界面拘鞋。
具體如何做呢?
1矢门、首先我們先來(lái)為 AppB 搭建兩個(gè)頁(yè)面 Page1 和 Page2盆色。這里用導(dǎo)航控制器 Push 兩個(gè)ViewController,通過(guò) Storyboard Segue設(shè)置兩個(gè) ViewController 的標(biāo)識(shí)符綁定祟剔,分別為 "homeToPage1" 和 "homeToPage2"隔躲。
搭建兩個(gè)頁(yè)面Page1和Page2
設(shè)置Page1ViewController的標(biāo)識(shí)符
2、在應(yīng)用程序AppA中添加兩個(gè)用來(lái)點(diǎn)擊跳轉(zhuǎn)的 Button物延,一個(gè)跳轉(zhuǎn)到Page1宣旱,一個(gè)跳轉(zhuǎn)到 Page2,并監(jiān)聽(tīng)點(diǎn)擊事件叛薯,添加跳轉(zhuǎn)代碼浑吟。
添加兩個(gè)跳轉(zhuǎn)按鈕
- (IBAction)jumbToAPPBPage1:(id)sender {
// 1、獲取應(yīng)用程序APPB 的 URL Scheme
NSURL *appBUrl = [NSURL URLWithString:@"APPB://Page1"];
// 2耗溜、判斷手機(jī)中是否安裝了對(duì)應(yīng)的程序
if ([[UIApplication sharedApplication] canOpenURL:appBUrl]) {
// 3组力、打開(kāi)應(yīng)用程序 APPB
[[UIApplication sharedApplication] openURL:appBUrl options:@{} completionHandler:nil];
} else {
NSLog(@"沒(méi)有安裝");
}
}
- (IBAction)jumbToAPPBPage2:(id)sender {
// 1、獲取應(yīng)用程序APPB 的 URL Scheme
NSURL *appBUrl = [NSURL URLWithString:@"APPB://Page2"];
// 2抖拴、判斷手機(jī)中是否安裝了對(duì)應(yīng)的程序
if ([[UIApplication sharedApplication] canOpenURL:appBUrl]) {
// 3燎字、打開(kāi)應(yīng)用程序 APPB
[[UIApplication sharedApplication] openURL:appBUrl options:@{} completionHandler:nil];
} else {
NSLog(@"沒(méi)有安裝");
}
}
3、在應(yīng)用App-B中通過(guò)AppDelegate監(jiān)聽(tīng)跳轉(zhuǎn),進(jìn)行判斷轩触,執(zhí)行不同頁(yè)面的跳轉(zhuǎn)
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
// 1.獲取導(dǎo)航欄控制器
UINavigationController *rootNav = (UINavigationController *)self.window.rootViewController;
// 2.獲得主控制器
ViewController *mainVc = [rootNav.childViewControllers firstObject];
// 3.每次跳轉(zhuǎn)前必須是在跟控制器(細(xì)節(jié))
[rootNav popToRootViewControllerAnimated:NO];
// 4.根據(jù)字符串關(guān)鍵字來(lái)跳轉(zhuǎn)到不同頁(yè)面
if ([url.absoluteString containsString:@"Page1"]) { // 跳轉(zhuǎn)到應(yīng)用AppB的Page1頁(yè)面
// 根據(jù)segue標(biāo)示進(jìn)行跳轉(zhuǎn)
[mainVc performSegueWithIdentifier:@"homeToPage1" sender:nil];
} else if ([url.absoluteString containsString:@"Page2"]) { // 跳轉(zhuǎn)到應(yīng)用AppB的Page2頁(yè)面
// 根據(jù)segue標(biāo)示進(jìn)行跳轉(zhuǎn)
[mainVc performSegueWithIdentifier:@"homeToPage2" sender:nil];
}
return YES;
}
具體效果如下:
AppA 跳轉(zhuǎn)到 AppB 的特定界面
6寞酿、從 應(yīng)用B 跳轉(zhuǎn)回 應(yīng)用A
1. 步驟分析:
我們想要從 應(yīng)用B 再跳轉(zhuǎn)回 應(yīng)用A,那么在跳轉(zhuǎn)到 應(yīng)用B 的時(shí)候脱柱,還應(yīng)將 應(yīng)用A 的URL Schemes 傳遞過(guò)來(lái)伐弹。這樣我們才能判斷應(yīng)該 跳轉(zhuǎn)回 哪個(gè)應(yīng)用程序。
這樣我們指定一個(gè)傳遞 URL的規(guī)則:協(xié)議頭:// 應(yīng)用B 的URL Schemes? 應(yīng)用A的URL Schemes榨为。即:AppB://Page1?AppA惨好。
說(shuō)明:
AppB 是跳轉(zhuǎn)過(guò)來(lái)的 應(yīng)用AppB 的URL Schemes;
Page1 是用來(lái)區(qū)別跳轉(zhuǎn)頁(yè)面的標(biāo)識(shí)随闺;
? 是分割符日川;
AppA 是跳轉(zhuǎn)回的 應(yīng)用 AppA 的 URL Schemes
2、我們根據(jù)傳遞來(lái)的數(shù)據(jù)矩乐,進(jìn)行反跳回去龄句。
2.1、之前我們?cè)?應(yīng)用AppB 中通過(guò) AppDelegate 執(zhí)行不同頁(yè)面的跳轉(zhuǎn)散罕。在對(duì)應(yīng)方法中我們可以拿到完整的 URL分歇,在主控制器ViewController中設(shè)定一個(gè)屬性,將該URL保存在主控制器中欧漱。
2.1职抡、在主控制器中我們可以通過(guò) - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender; 方法獲取將要跳轉(zhuǎn)的頁(yè)面控制器。
2.3误甚、在將要跳轉(zhuǎn)的頁(yè)面控制器中定義一個(gè)屬性缚甩,用于接受、截取出跳轉(zhuǎn)回的應(yīng)用(即AppA)的URL Schemes窑邦,執(zhí)行跳轉(zhuǎn)擅威。
3、具體步驟:
3.1奕翔、準(zhǔn)備步驟:
3.1.1裕寨、因?yàn)槲覀兿胍D(zhuǎn)回 應(yīng)用A,首先我們要先設(shè)置應(yīng)用AppA的URL Schemes派继,將其設(shè)置為AppA。同時(shí)在應(yīng)用AppB中添加白名單捻艳。具體操作和之前相似驾窟。
3.1.2、在AppB項(xiàng)目中的Page1和Page2兩個(gè)頁(yè)面各添加一個(gè)Button认轨,用于跳轉(zhuǎn)回 AppA绅络。同時(shí)添加 Page1 和 Page2 的頁(yè)面控制器 Page1ViewController 和Page2ViewController。
添加Page1和Page2的頁(yè)面控制器Page1ViewController和Page2ViewController
4、 實(shí)現(xiàn)步驟
4.1恩急、在 應(yīng)用AppA 中修改傳遞的URL杉畜。
分別修改為:@"APPB://?APPA"、@"APPB://Page1?APPA"衷恭、@"APPB://Page2?APPA"
4.2此叠、在 AppB 的主控制器 ViewController中增加一條屬性 @property (nonatomic, copy) NSString *urlString;,并在AppB中通過(guò)AppDelegate中保存完整的URL随珠。
4.3灭袁、在將要跳轉(zhuǎn)的頁(yè)面控制器 Page1ViewController 和 Page2ViewController 中定義一個(gè)屬性@property (nonatomic, copy) NSString *urlString;,用于接受窗看、截取出跳轉(zhuǎn)回的應(yīng)用(即AppA)的 URL Schemes茸歧,執(zhí)行跳轉(zhuǎn)。
4.4显沈、重寫App-B的主控制器的- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender方法软瞎。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"homeToPage1"]) {
// 獲得將要跳轉(zhuǎn)的界面Page1的控制器
Page1ViewController *Page1Vc = segue.destinationViewController;
// 保存完整的App-A的URL給跳轉(zhuǎn)界面Page1
Page1Vc.urlString = self.urlString;
} else if ([segue.identifier isEqualToString:@"homeToPage2"]) {
// 獲得將要跳轉(zhuǎn)的界面Page2的控制器
Page2ViewController *Page2Vc = segue.destinationViewController;
// 保存完整的App-A的URL給跳轉(zhuǎn)界面Page1
Page2Vc.urlString = self.urlString;
}
}
5、在對(duì)應(yīng)界面控制器Page1ViewController和Page2ViewController中實(shí)現(xiàn)跳轉(zhuǎn)代碼
- Page1ViewController.m
- (IBAction)page1BackToAppA:(id)sender {
// 1.拿到對(duì)應(yīng)應(yīng)用程序的URL Scheme
NSString *urlSchemeString = [[self.urlString componentsSeparatedByString:@"?"] lastObject];
NSString *urlString = [urlSchemeString stringByAppendingString:@"://"];
// 2.獲取對(duì)應(yīng)應(yīng)用程序的URL
NSURL *url = [NSURL URLWithString:urlString];
// 3.判斷是否可以打開(kāi)
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}
}
- Page2ViewController.m
- (IBAction)page2BackToAppA:(id)sender {
// 1.拿到對(duì)應(yīng)應(yīng)用程序的URL Scheme
NSString *urlSchemeString = [[self.urlString componentsSeparatedByString:@"?"] lastObject];
NSString *urlString = [urlSchemeString stringByAppendingString:@"://"];
// 2.獲取對(duì)應(yīng)應(yīng)用程序的URL
NSURL *url = [NSURL URLWithString:urlString];
// 3.判斷是否可以打開(kāi)
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}
}
具體效果如下: