应用间相互跳转实现原理:
keyword(相关知识点):
应用间相互跳转、URL Schemes、
[[UIApplication sharedApplication]openURL:url options:@{} completionHandler:nil]、performSegueWithIdentifier
github上Demo地址:
https://github.com/yaocunli/apptiaoZhuan
- 跳转原理:
通过设置跳转到应用B的URL Schemes(自定义的协议头),应用B将其自身“绑定”到一个自定义URL Schemes上,就可以从应用A中利用应用B的URL Schemes启动应用B了。
一:应用A跳转到应用B
iOS9引入了白名单的概念。
注意:
1. 如果是iOS9之前的模拟器或是真机,那么在相同的模拟器中先后运行FirstApp、SecondApp,点击按钮,就可以实现跳转了。
2. 如果是iOS9之后的模拟器或是真机,那么则需要再在应用程序FirstApp中将SecondApp的URL Schemes添加到白名单中,原因和做法如下。
* iOS9引入了白名单的概念。
* 在iOS9中,如果使用 canOpenURL:方法,该方法所涉及到的 URL Schemes 必须在”Info.plist”中将它们列为白名单,否则不能使用。key叫做LSApplicationQueriesSchemes (就是添加可查询的schemes),键值内容是对应应用程序的URL Schemes。
具体做法就是在FirstApp的Info文件中,添加LSApplicationQueriesSchemes数组,然后添加键值为SecondApp的字符串。
注意:LSApplicationQueriesSchemes手动添加,系统没有智能提示!!!
绑定按钮代码如下:
- (IBAction)ToSecondApp:(id)sender {
// 取得需要跳转到的app的url-scheme
NSURL * url = [NSURL URLWithString:@"SecondApp://"];
// 判断是否安转
if ([[UIApplication sharedApplication] canOpenURL:url]) {
// if安装的话,打开
[[UIApplication sharedApplication]openURL:url options:@{} completionHandler:nil];
} else {
// 或者跳转到的app的对应的appstore的网址
NSLog(@"还没有安装");
}
}
二:应用A跳转到应用B的特定界面
1.很多时候,我们做应用程序之间的跳转并不只是跳转到其他程序就可以了,而是要跳转到其他程序的特定页面上。比如我们在浏览网页时,会有分享到微信朋友圈或是分享给微信朋友,这就需要跳转到微信朋友圈界面或是微信朋友选择界面。
2.首先我们先来为SecondApp搭建两个页面Page1和Page2。这里用导航控制器Push两个ViewController,通过Storyboard Segue设置两个ViewController的标识符绑定,分别为”homeToPage1”和”homeToPage2”。
3.在应用程序FirstApp中添加两个用来点击跳转的Button,一个跳转到Page1,一个跳转到Page2,并监听点击事件,添加跳转代码。
其实就是拷贝第一步的代码,每个url给他一个不一样的标识,便于SecondApp逻辑判断。
4.在应用SecondApp中通过AppDelegate下面的代理方法中监听跳转,进行判断,执行不同页面的跳转(每次程序通过url启动,都会执行下面的代理方法)
-(BOOL)application:(UIApplication )application openURL:(NSURL )url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
按钮绑定代码:
- (IBAction)ToPageOne:(id)sender {
// 取得需要跳转到的app的url-scheme
NSURL * url = [NSURL URLWithString:@"SecondApp://page1"];
// 判断是否安转
if ([[UIApplication sharedApplication] canOpenURL:url]) {
// if安装的话,打开
[[UIApplication sharedApplication]openURL:url options:@{} completionHandler:nil];
} else {
// 或者跳转到的app的对应的appstore的网址
NSLog(@"还没有安装");
}
}
- (IBAction)ToPageTwo:(id)sender {
// 取得需要跳转到的app的url-scheme
NSURL * url = [NSURL URLWithString:@"SecondApp://page2"];
// 判断是否安转
if ([[UIApplication sharedApplication] canOpenURL:url]) {
// if安装的话,打开
[[UIApplication sharedApplication]openURL:url options:@{} completionHandler:nil];
} else {
// 或者跳转到的app的对应的appstore的网址
NSLog(@"还没有安装");
}
}
SecondApp中AppDelegate响应方法:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
UINavigationController * rootNav = (UINavigationController*)self.window.rootViewController;
// 获取到主控制器
ViewController * homeVC = [rootNav.childViewControllers firstObject];
// 每次跳转前,必须在跟控制器,否则会出现导航栏返回按钮,可以返回多次的错误。
[rootNav popToRootViewControllerAnimated:NO];
if ([url.absoluteString containsString:@"page1"]) {
// 跳转到应用App-B的Page1页面
// 根据segue标示进行跳转
[homeVC performSegueWithIdentifier:@"homeToPage1" sender:nil];
} else if ([url.absoluteString containsString:@"page2"]) {
// 跳转到应用App-B的Page2页面
// 根据segue标示进行跳转
[homeVC performSegueWithIdentifier:@"homeToPage2" sender:nil];
}
return YES;
}
三:从应用B跳转回应用A
我们想要从应用B再跳转回应用A,那么在跳转到应用B的时候,还应将应用A的URL Schemes传递过来。这样我们才能判断应该跳转回哪个应用程序。
- (IBAction)ToPageOne:(id)sender {
// 取得需要跳转到的app的url-scheme
NSURL * url = [NSURL URLWithString:@"SecondApp://page1?FirstApp"];
// 判断是否安转
if ([[UIApplication sharedApplication] canOpenURL:url]) {
// if安装的话,打开
[[UIApplication sharedApplication]openURL:url options:@{} completionHandler:nil];
} else {
// 或者跳转到的app的对应的appstore的网址
NSLog(@"还没有安装");
}
}
我们根据传递来的数据,进行反跳回去。
1. 之前我们在应用SecondApp中通过AppDelegate执行不同页面的跳转。在对应方法中我们可以拿到完整的URL,在主控制器ViewController中设定一个属性,将该URL保存在主控制器中。
2. 在主控制器中我们可以通过- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;方法获取将要跳转的页面控制器。
3. 在将要跳转的页面控制器中定义一个属性,用于接受、截取出跳转回的应用(即FirstApp)的URL Schemes,执行跳转。
实现步骤:这块有几个文件中写了代码,写两遍就觉得简单了!!!
1. 在FirstApp中修改传递的URL。
2. 在SecondApp的主控制器ViewController中增加一条属性@property (nonatomic, copy) NSString *urlString;,并在SecondApp中通过AppDelegate中保存完整的URL。
homeVC.urlstring = url.absoluteString;
3.在将要跳转的页面控制器Page1ViewController和Page2ViewController中定义一个属性@property (nonatomic, copy) NSString *urlString;,用于接受、截取出跳转回的应用(即FirstApp)的URL Schemes,执行跳转。
4.重写SecondApp的主控制器的- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender方法。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"homeToPage1"]) {
// 获得将要跳转的界面Page1的控制器
FirstPageViewController *Page1Vc = segue.destinationViewController;
// 保存完整的App-A的URL给跳转界面Page1
Page1Vc.urlString = self.urlstring;
} else if ([segue.identifier isEqualToString:@"homeToPage2"]) {
// 传给第二个界面,这里不写了,和上步一样
}
}
5.在对应界面控制器Page1ViewController实现跳转代码(Page2ViewController中写法一样,此处不写了!)
- (IBAction)BackToFirstApp:(id)sender {
// 1.拿到对应应用程序的URL Scheme
NSString *urlSchemeString = [[self.urlString componentsSeparatedByString:@"?"] lastObject];
NSString *urlString = [urlSchemeString stringByAppendingString:@"://"];
// 2.获取对应应用程序的URL
NSURL *url = [NSURL URLWithString:urlString];
// 3.判断是否可以打开
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication]openURL:url options:@{} completionHandler:nil];
}
}