在iOS开发的过程当中,咱们常常会遇到须要从一个应用程序A跳转到另外一个应用程序B的场景。这就须要咱们掌握iOS应用程序之间的相互跳转知识。html
下面来看看咱们在开发过程当中遇到的应用场景。ios
那么咱们如何实现应用间的相互跳转呢?先来看下原理。数组
在iOS中打开一个应用程序只须要拿到这个应用程序的协议头便可,因此咱们只需配置应用程序的协议头便可。微信
假设有应用A和应用B两个应用,如今须要从应用A跳转到应用B中。app
具体怎么作呢,下面一步步来教你,先来个简单点的:从应用A跳转到应用B。ide
选择项目App-B -> TARGETS -> Info -> URL Types -> URL Schemes,设置App-B的URL Schemes为AppB。学习
在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。ui
CFBundleURLSchemes
: 是一个数组,能够定义多个URL Schemes。这里不须要再后面追加://,若是设置为myapp, 那么自定义的url就是myapp://。atom
在应用程序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添加到白名单中,缘由和作法以下。
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的特定界面。
不少时候,咱们作应用程序之间的跳转并不仅是跳转到其余程序就能够了,而是要跳转到其余程序的特定页面上。好比咱们在浏览网页时,会有分享到微信朋友圈或是分享给微信朋友,这就须要跳转到微信朋友圈界面或是微信朋友选择界面。
具体如何作呢?
Page1
和Page2
。这里用导航控制器Push两个ViewController,经过Storyboard Segue设置两个ViewController的标识符绑定,分别为"homeToPage1"和"homeToPage2"。- (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; }
具体效果以下:
协议头://应用B的URL Schemes?应用A的URL Schemes
。即:AppB://Page1?AppA
。AppDelegate
执行不一样页面的跳转。在对应方法中咱们能够拿到完整的URL,在主控制器ViewController中设定一个属性,将该URL保存在主控制器中。- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;
方法获取将要跳转的页面控制器。@"AppB://?AppA"
、@"AppB://Page1?AppA"
、@"AppB://Page2?AppA"
@property (nonatomic, copy) NSString *urlString;
,并在App-B中经过AppDelegate
中保存完整的URL。@property (nonatomic, copy) NSString *urlString;
,用于接受、截取出跳转回的应用(即App-A)的URL Schemes,执行跳转。- (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; } }
- (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应用。