iOS - 白名单应用间相互跳转
1. 应用间相互跳转简介
在iOS开发的过程中,我们经常会遇到需要从一个应用程序A跳转到另一个应用程序B的场景。这就需要我们掌握iOS应用程序之间的相互跳转知识。
下面来看看我们在开发过程中遇到的应用场景。
2. 应用间相互跳转应用场景
- 使用第三方用户登录,跳转到需授权的App。如QQ登录,微信登录等。
- 需要用户授权,还需要"返回到调用的程序,同时返回授权的用户名、密码"。
- 应用程序推广,跳转到另一个应用程序(本机已经安装),或者跳转到iTunes并显示应用程序下载页面(本机没有安装)。
- 第三方支付,跳转到第三方支付App,如支付宝支付,微信支付。
- 内容分享,跳转到分享App的对应页面,如分享给微信好友、分享给微信朋友圈、分享到微博。
- 显示位置、地图导航,跳转到地图应用。
- 使用系统内置程序,跳转到打电话、发短信、发邮件、Safari打开网页等内置App中。
那么我们如何实现应用间的相互跳转呢?先来看下原理。
3. 应用间相互跳转实现原理
在iOS中打开一个应用程序只需要拿到这个应用程序的协议头即可,所以我们只需配置应用程序的协议头即可。
假设有应用A和应用B两个应用,现在需要从应用A跳转到应用B中。
- 原理:通过设置跳转到应用B的URL Schemes(自定义的协议头)About Apple URL Schemes,应用B将其自身“绑定”到一个自定义URL Schemes上,就可以从应用A中利用应用B的URL Schemes启动应用B了。
具体怎么做呢,下面一步步来教你,先来个简单点的:从应用A跳转到应用B。
4. 应用A跳转到应用B
- 首先我们用Xcode创建两个iOS应用程序项目,项目名称分别为App-A、App-B。
选择项目App-B -> TARGETS -> Info -> URL Types -> URL Schemes,设置App-B的URL Schemes为AppB。
设置App-B的URL Schemes在B应用的info.plist文件下加入 URL Types (这个是文件格式,上面的是界面操作)
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.wlnana17.B</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>CFBundleURLName
: 是URL Identifier,是自定义的URL Scheme的名字,建议采用反转域名的方法保证该名字的唯一性,比如come.yourCompany.yourApp。CFBundleURLSchemes
: 是一个数组,可以定义多个URL Schemes。这里不需要再后面追加://,如果设置为myapp, 那么自定义的url就是myapp://。在应用程序App-A中添加一个用来点击跳转的Button,并监听点击事件,添加跳转代码。
添加跳转按钮
- (IBAction)jumpToAppB:(id)sender {
// 1.获取应用程序App-B的URL Scheme
NSURL *appBUrl = [NSURL URLWithString:@"AppB://"]; // 2.判断手机中是否安装了对应程序
if ([[UIApplication sharedApplication] canOpenURL:appBUrl]) {
// 3. 打开应用程序App-B
[[UIApplication sharedApplication] openURL:appBUrl];
} else {
NSLog(@"没有安装");
}
}如果是iOS9之前的模拟器或是真机,那么在相同的模拟器中先后运行App-B、App-A,点击按钮,就可以实现跳转了。
如果是iOS9之后的模拟器或是真机,那么则需要再在应用程序App-A中将App-B的URL Schemes添加到白名单中,原因和做法如下。
- iOS9引入了白名单的概念。
- 在iOS9中,如果使用
canOpenURL:
方法,该方法所涉及到的 URL Schemes 必须在"Info.plist"中将它们列为白名单,否则不能使用。key叫做LSApplicationQueriesSchemes ,键值内容是对应应用程序的URL Schemes。苹果为什么要这么做?
在 iOS9 之前,你可以使用 canOpenURL: 监测用户手机里到底装没装微信,装没装微博。但是也有一些别有用心的 App ,这些 App 有一张常用 App 的 URL scheme,然后他们会多次调用canOpenURL: 遍历该表,来监测用户手机都装了什么 App ,比如这个用户装了叫“大姨妈”的App,你就可以知道这个用户是女性,你就可以只推给这个用户女性用品的广告。这是侵犯用户隐私的行为。
具体做法就是在App-A的Info文件中,添加LSApplicationQueriesSchemes数组,然后添加键值为AppB的字符串。
添加白名单之后在相同的模拟器中先后运行App-B、App-A,点击按钮,就可以实现跳转了。
具体效果如下图所示。
下边学习以下从应用A跳转到应用B的特定界面。
5. 应用A跳转到应用B的特定界面
很多时候,我们做应用程序之间的跳转并不只是跳转到其他程序就可以了,而是要跳转到其他程序的特定页面上。比如我们在浏览网页时,会有分享到微信朋友圈或是分享给微信朋友,这就需要跳转到微信朋友圈界面或是微信朋友选择界面。
具体如何做呢?
- 首先我们先来为App-B搭建两个页面
Page1
和Page2
。这里用导航控制器Push两个ViewController,通过Storyboard Segue设置两个ViewController的标识符绑定,分别为"homeToPage1"和"homeToPage2"。
- 在应用程序App-A中添加两个用来点击跳转的Button,一个跳转到Page1,一个跳转到Page2,并监听点击事件,添加跳转代码。
- (IBAction)jumpToAppBPage1:(id)sender {
// 1.获取应用程序App-B的Page1页面的URL
NSURL *appBUrl = [NSURL URLWithString:@"AppB://Page1"]; // 2.判断手机中是否安装了对应程序
if ([[UIApplication sharedApplication] canOpenURL:appBUrl]) {
// 3. 打开应用程序App-B的Page1页面
[[UIApplication sharedApplication] openURL:appBUrl];
} else {
NSLog(@"没有安装");
}
} - (IBAction)jumpToAppBPage2:(id)sender {
// 1.获取应用程序App-B的Page2页面的URL
NSURL *appBUrl = [NSURL URLWithString:@"AppB://Page2"]; // 2.判断手机中是否安装了对应程序
if ([[UIApplication sharedApplication] canOpenURL:appBUrl]) {
// 3. 打开应用程序App-B的Page2页面
[[UIApplication sharedApplication] openURL:appBUrl];
} 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"]) { // 跳转到应用App-B的Page1页面
// 根据segue标示进行跳转
[mainVc performSegueWithIdentifier:@"homeToPage1" sender:nil];
} else if ([url.absoluteString containsString:@"Page2"]) { // 跳转到应用App-B的Page2页面
// 根据segue标示进行跳转
[mainVc performSegueWithIdentifier:@"homeToPage2" sender:nil];
} return YES;
}
具体效果如下:
6.从应用B跳转回应用A
1. 步骤分析:
- 我们想要从应用B再跳转回应用A,那么在跳转到应用B的时候,还应将应用A的URL Schemes传递过来。这样我们才能判断应该跳转回哪个应用程序。
- 这样我们指定一个传递URL的规则:
协议头://应用B的URL Schemes?应用A的URL Schemes
。即:AppB://Page1?AppA
。 - 说明:
- AppB是跳转过来的应用App-B的URL Schemes;
- Page1是用来区别跳转页面的标识;
- ? 是分割符;
- AppA是跳转回的应用App-A的URL Schemes
- 我们根据传递来的数据,进行反跳回去。
- 之前我们在应用App-B中通过
AppDelegate
执行不同页面的跳转。在对应方法中我们可以拿到完整的URL,在主控制器ViewController中设定一个属性,将该URL保存在主控制器中。 - 在主控制器中我们可以通过
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;
方法获取将要跳转的页面控制器。 - 在将要跳转的页面控制器中定义一个属性,用于接受、截取出跳转回的应用(即App-A)的URL Schemes,执行跳转。
- 之前我们在应用App-B中通过
2. 具体步骤:
1. 准备步骤:
- 因为我们想要跳转回应用A,首先我们要先设置应用App-A的URL Schemes,将其设置为AppA。同时在应用App-B中添加白名单。具体操作和之前相似。
- 在App-B项目中的Page1和Page2两个页面各添加一个Button,用于跳转回App-A。同时添加Page1和Page2的页面控制器Page1ViewController和Page2ViewController。
2. 实现步骤
- 在App-A中修改传递的URL。
- 分别修改为:
@"AppB://?AppA"
、@"AppB://Page1?AppA"
、@"AppB://Page2?AppA"
- 在App-B的主控制器ViewController中增加一条属性
@property (nonatomic, copy) NSString *urlString;
,并在App-B中通过AppDelegate
中保存完整的URL。 - 在将要跳转的页面控制器Page1ViewController和Page2ViewController中定义一个属性
@property (nonatomic, copy) NSString *urlString;
,用于接受、截取出跳转回的应用(即App-A)的URL Schemes,执行跳转。 - 重写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;
}
}
- 在对应界面控制器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];
}
}
具体效果如下:
也可以在Safari中,键入使用定制模式的URL(myapp://),确认是否启动B应用,就可以从Safari中打开注册的B应用。
iOS - 白名单应用间相互跳转的更多相关文章
- 【转】iOS开发--一步步教你彻底学会『iOS应用间相互跳转』
1. 应用间相互跳转简介 在iOS开发的过程中,我们经常会遇到需要从一个应用程序A跳转到另一个应用程序B的场景.这就需要我们掌握iOS应用程序之间的相互跳转知识. 下面来看看我们在开发过程中遇到的应用 ...
- iOS应用间相互跳转
使用第三方用户登录,跳转到需授权的App.如QQ登录,微信登录等. 需要用户授权,还需要"返回到调用的程序,同时返回授权的用户名.密码". 应用程序推广,跳转到另一个应用程序(本机 ...
- iOS白名单设置
在做分享.支付的时候需要跳转到对应的app,这里有需要设置的白名单列表<key>LSApplicationQueriesSchemes</key> <array> ...
- App间相互跳转及图片分享
A-app: Info--URL Types--URL Schemes:A-app(一个标识,允许别的app调用本App) info.plist 添加白名单: LSApplicationQueries ...
- iOS - (两个APP之间的跳转)
一个程序若要跳到另一个程序.需要在目标程序的plist文件里面修改: 打开info.plist,添加一项URL types 展开URL types,再展开Item0,将Item0下的URL ident ...
- IOS 应用跳转 (IOS9白名单)
跳转到指定app的实现 IOS中应用的跳转是通过URL实现的,因此在实现应用跳转之前我们要设置一下对应的URL. 图一(寻找配置软件的URL) 图二(具体配置选项) 注意: 如果IOS版本为IOS9 ...
- ios ionic3 跳转第三方地图 xcode加入白名单
之前我有篇随笔讲的是ionic3应用内跳转第三方地图应用的方法 忘了记录在ios内是需要把你用到的第三方地图应用加入跳转URL白名单内的 第三个是高德地图 iosamap 第四个是百度地图 baidu ...
- iOS应用程序开发之应用间的跳转(用着微信等第三方分享登陆)
简介 配置和实现 判断应用启动方式 一.简介 最实际项目开发中,我们难免会遇到需要从一个应用跳转到另一个应用的情况.比如微信分享,实际就是一种应用间的跳转.但是有时候我们需要实现自己的两个应用间的跳转 ...
- IOS:程序的退出、App间的跳转
今天在做一个音乐播放器的项目,发现这个点击退出程序的功能不能实现终于找到了一些有用的资料,就去网上看了半天资料,下面是退出程序的代码: 在动画里面可以自己添加一些,动画,达到相应的效果. AppDel ...
随机推荐
- (笔记)Mysql命令create:创建数据库
create命令用于创建数据库. create命令格式:create database <数据库名>; 注意:创建数据库之前要先连接Mysql服务器. 1) 建立一个名为xhkdb的数据库 ...
- C语言中的控制语句: 判断、环循等;
列举这一部分的目的就是注意它的写法,尤其是 分号 : 的位置: 1. if-else if else 语句: if (表达式1) 语句1: else if (表达式2) 语句2: else 语句3: ...
- C++ 把枚举变量的名称,直接当字符串使用方法 字符串化符号 #
#include <stdio.h> #include <typeinfo> #include <string> using namespace std; enum ...
- 如何在集群中获得处理本次请求的web容器的端口号?
系统四台机器,每台机器部署四个Tomcat Web容器.现需要根据端口号随机切换到映射的数据源,若一台机器一个Tomcat则用IP识别,可现在一台机器四个Tomcat,因此还需要获得Web容器的端口号 ...
- (资源)OpenStack IRC资源
OpenStack的IRC频道列表 如何在浏览器上进入OpenStack的频道(具体的频道可以参考前面的频道列表) 频道聊天日志和会议日志 这里我使用mIRC而不是浏览器接入IRC,OpenStack ...
- PLSQL Developer连接不上64位Oracle 10g的解决办法
下载instantclient-basic-win32-10.2.0.4.zip 假设Oracle 10g的安装目录为D:\oracle\product\10.2.0\db1 首先,将instantc ...
- MAVEN最佳实践:模块划分
转自:http://juvenshun.iteye.com/blog/305865 所有用Maven管理的真实的项目都应该是分模块的,每个模块都对应着一个pom.xml.它们之间通过继承和聚合(也称作 ...
- 【WP8】仿QQ提示消息
WP版的QQ提示消息的时候从顶部滑入,3秒后从顶部滑出,本文模仿该效果实现一个MessageToastManager类用于显示提示消息 思路很简单,就是动画而已,支持配置颜色和回掉 // ****** ...
- windows 下查看端口占用情况
windows下面查看端口占用情况: netstat -ano|findstr "8888" TCP 127.0.0.1:8888 0.0.0.0:0 LISTENING 6876 ...
- BarTender 2016表单中的“秤显示”控件
BarTender 2016中的表单是一个非常实用的工具,它可以实现数据输出提示,查询提示和同一表单的记录选择.这些都离开可供添加的控件,“秤显示”控件也是我们打印尝尝需要涉及的,今天我们就来看看什么 ...