iOS_应用间相互跳转

资料来源 & Demo
CocoaChina 一个强大的学习网址!!!

1. 应用间相互跳转简介

在 iOS 开发的过程中,我们经常会遇到需要从一个 应用程序A 跳转到另一个 应用程序B 的场景。这就需要我们掌握 iOS 应用程序之间的相互跳转知识。

2. 应用间相互跳转应用场景

使用第三方用户登录,跳转到需授权的App。如QQ登录,微信登录等。
需要用户授权,还需要"返回到调用的程序,同时返回授权的用户名、密码"。
应用程序推广,跳转到另一个应用程序(本机已经安装),或者跳转到 iTunes 并显示应用程序下载页面(本机没有安装)。
第三方支付,跳转到第三方支付App,如支付宝支付,微信支付。
内容分享,跳转到分享App的对应页面,如分享给微信好友、分享给微信朋友圈、分享到微博。
显示位置、地图导航,跳转到地图应用。
使用系统内置程序,跳转到打电话、发短信、发邮件、Safari打开网页等内置App中。

3. 应用间相互跳转实现原理

在 iOS 中打开一个应用程序只需要拿到这个应用程序的 ** 协议头 ** 即可,所以我们只需配置应用程序的协议头即可。
假设有 应用A 和 应用B 两个应用,现在需要从 应用A 跳转到 应用B 中。
原理: 通过设置跳转到应用B的URL Schemes(自定义的协议头),应用B将其自身“绑定”到一个自定义 URL Schemes 上,就可以从 应用A 中利用 应用B 的 URL Schemes 启动应用B了。

4. 应用A跳转到应用B

1、首先我们用Xcode创建两个iOS应用程序项目,项目名称分别为AppA、AppB。
2、选择项目AppB -> TARGETS -> Info -> URL Types -> URL Schemes,设置AppB的URL Schemes为 AppB。

3、在应用程序App-A中添加一个用来点击跳转的Button,并监听点击事件,添加跳转代码。

相关代码

- (IBAction)jumbToAPPB:(id)sender {
    // 1、获取应用程序APPB 的 URL Scheme
    NSURL *appBUrl = [NSURL URLWithString:@"APPB://"];
    // 2、判断手机中是否安装了对应的程序
    if ([[UIApplication sharedApplication] canOpenURL:appBUrl]) {
        // 3、打开应用程序 APPB
        [[UIApplication sharedApplication] openURL:appBUrl options:@{} completionHandler:nil];
    } else {
        NSLog(@"没有安装");
    }
}

4、如果是 iOS 9 之前的模拟器或是真机,那么在相同的模拟器中先后运行 AppB、AppA,点击按钮,就可以实现跳转了。
5、如果是 iOS 9 之后的模拟器或是真机,那么则需要再在应用程序 AppA 中将 AppB 的 URL Schemes 添加到白名单中,原因和做法如下:
iOS 9 引入了白名单的概念。
在 iOS 9 中,如果使用 canOpenURL: 方法,该方法所涉及到的 URL Schemes 必须在"Info.plist"中将它们列为白名单,否则不能使用。key叫做LSApplicationQueriesSchemes ,键值内容是对应应用程序的 URL Schemes。

具体做法就是在 AppA 的 Info 文件中,添加 LSApplicationQueriesSchemes 数组,然后添加键值为 AppB 的字符串。

添加 LSApplicationQueriesSchemes 数组,然后添加键值为 AppB 的字符串
添加白名单之后在相同的模拟器中先后运行 AppB、AppA,点击按钮,就可以实现跳转了。
具体效果如下图所示。

5. 应用A 跳转到 应用B 的特定界面

很多时候,我们做应用程序之间的跳转并不只是跳转到其他程序就可以了,而是要跳转到其他程序的特定页面上。比如我们在浏览网页时,会有分享到微信朋友圈或是分享给微信朋友,这就需要跳转到微信朋友圈界面或是微信朋友选择界面。

具体如何做呢?

1、首先我们先来为 AppB 搭建两个页面 Page1 和 Page2。这里用导航控制器 Push 两个ViewController,通过 Storyboard Segue设置两个 ViewController 的标识符绑定,分别为 "homeToPage1" 和 "homeToPage2"。

搭建两个页面Page1和Page2

设置Page1ViewController的标识符

2、在应用程序AppA中添加两个用来点击跳转的 Button,一个跳转到Page1,一个跳转到 Page2,并监听点击事件,添加跳转代码。

添加两个跳转按钮
- (IBAction)jumbToAPPBPage1:(id)sender {
    // 1、获取应用程序APPB 的 URL Scheme
    NSURL *appBUrl = [NSURL URLWithString:@"APPB://Page1"];
    // 2、判断手机中是否安装了对应的程序
    if ([[UIApplication sharedApplication] canOpenURL:appBUrl]) {
        // 3、打开应用程序 APPB
        [[UIApplication sharedApplication] openURL:appBUrl options:@{} completionHandler:nil];
    } else {
        NSLog(@"没有安装");
    }
}

- (IBAction)jumbToAPPBPage2:(id)sender {
    // 1、获取应用程序APPB 的 URL Scheme
    NSURL *appBUrl = [NSURL URLWithString:@"APPB://Page2"];
    // 2、判断手机中是否安装了对应的程序
    if ([[UIApplication sharedApplication] canOpenURL:appBUrl]) {
        // 3、打开应用程序 APPB
        [[UIApplication sharedApplication] openURL:appBUrl options:@{} completionHandler:nil];
    } else {
        NSLog(@"没有安装");
    }
}

3、在应用App-B中通过AppDelegate监听跳转,进行判断,执行不同页面的跳转

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    
    // 1.获取导航栏控制器
    UINavigationController *rootNav = (UINavigationController *)self.window.rootViewController;
    // 2.获得主控制器
    ViewController *mainVc = [rootNav.childViewControllers firstObject];
    
    // 3.每次跳转前必须是在跟控制器(细节)
    [rootNav popToRootViewControllerAnimated:NO];
    
    // 4.根据字符串关键字来跳转到不同页面
    if ([url.absoluteString containsString:@"Page1"]) { // 跳转到应用AppB的Page1页面
        // 根据segue标示进行跳转
        [mainVc performSegueWithIdentifier:@"homeToPage1" sender:nil];
    } else if ([url.absoluteString containsString:@"Page2"]) { // 跳转到应用AppB的Page2页面
        // 根据segue标示进行跳转
        [mainVc performSegueWithIdentifier:@"homeToPage2" sender:nil];
    }
    return YES;
}

具体效果如下:

AppA 跳转到 AppB 的特定界面


6、从 应用B 跳转回 应用A

1. 步骤分析:

我们想要从 应用B 再跳转回 应用A,那么在跳转到 应用B 的时候,还应将 应用A 的URL Schemes 传递过来。这样我们才能判断应该 跳转回 哪个应用程序。
这样我们指定一个传递 URL的规则:协议头:// 应用B 的URL Schemes? 应用A的URL Schemes。即:AppB://Page1?AppA
说明:
AppB 是跳转过来的 应用AppB 的URL Schemes;
Page1 是用来区别跳转页面的标识;
? 是分割符;
AppA 是跳转回的 应用 AppA 的 URL Schemes

2、我们根据传递来的数据,进行反跳回去。

2.1、之前我们在 应用AppB 中通过 AppDelegate 执行不同页面的跳转。在对应方法中我们可以拿到完整的 URL,在主控制器ViewController中设定一个属性,将该URL保存在主控制器中。
2.1、在主控制器中我们可以通过 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender; 方法获取将要跳转的页面控制器。
2.3、在将要跳转的页面控制器中定义一个属性,用于接受、截取出跳转回的应用(即AppA)的URL Schemes,执行跳转。

3、具体步骤:

3.1、准备步骤:
3.1.1、因为我们想要跳转回 应用A,首先我们要先设置应用AppA的URL Schemes,将其设置为AppA。同时在应用AppB中添加白名单。具体操作和之前相似。
3.1.2、在AppB项目中的Page1和Page2两个页面各添加一个Button,用于跳转回 AppA。同时添加 Page1 和 Page2 的页面控制器 Page1ViewController 和Page2ViewController。



添加Page1和Page2的页面控制器Page1ViewController和Page2ViewController

4、 实现步骤

4.1、在 应用AppA 中修改传递的URL。
分别修改为:@"APPB://?APPA"、@"APPB://Page1?APPA"、@"APPB://Page2?APPA"

4.2、在 AppB 的主控制器 ViewController中增加一条属性 @property (nonatomic, copy) NSString *urlString;,并在AppB中通过AppDelegate中保存完整的URL。

4.3、在将要跳转的页面控制器 Page1ViewController 和 Page2ViewController 中定义一个属性@property (nonatomic, copy) NSString *urlString;,用于接受、截取出跳转回的应用(即AppA)的 URL Schemes,执行跳转。

4.4、重写App-B的主控制器的- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender方法。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
   if ([segue.identifier isEqualToString:@"homeToPage1"]) {
       // 获得将要跳转的界面Page1的控制器
       Page1ViewController *Page1Vc = segue.destinationViewController;
       // 保存完整的App-A的URL给跳转界面Page1
       Page1Vc.urlString = self.urlString;
   } else if ([segue.identifier isEqualToString:@"homeToPage2"]) {
       // 获得将要跳转的界面Page2的控制器
       Page2ViewController *Page2Vc = segue.destinationViewController;
       // 保存完整的App-A的URL给跳转界面Page1
       Page2Vc.urlString = self.urlString;
   }
}
5、在对应界面控制器Page1ViewController和Page2ViewController中实现跳转代码
- Page1ViewController.m
- (IBAction)page1BackToAppA:(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];
   }
}
- Page2ViewController.m
- (IBAction)page2BackToAppA:(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];
   }
}

具体效果如下:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容