聲明:
本文章是參考:船長_的文章:http://www.reibang.com/p/732c5e1720d0 所寫赘来,請大家方便時移步船長_ 的博客為他點贊哎甲。
謝謝!
iOS 應用之間的跳轉玻墅,是通過設置"URL Scheme"來實現(xiàn)的燎字。
簡單來說:假設現(xiàn)在有兩個應用A與B肚吏,我們分別設置了A和B的"URL Scheme"蟹倾,作為這兩個App的標識缤削,并通過在A和B的程序中一些設置分扎,來達到應用跳轉的目的澄成。
具體的操作流程如下:
1、首先設置A與B的"URL Scheme":
1畏吓、A_URL.png
2墨状、B_URL.png
2、將A和B的"URL Scheme"添加到對方的白名單中:
蘋果公司在 iOS9之后 引入白名單概念菲饼。
在iOS9中肾砂,如果使用 canOpenURL: 方法,該方法所涉及到的 URL scheme 必須在"Info.plist"中將它們列為白名單宏悦,否則不能使用镐确。(白名單上限是50個)。
3饼煞、A_B_URLScheme.png
4源葫、B_A_URLScheme.png
PS:在 iOS9 之前,你可以使用
[[UIApplication sharedApplication] canOpenURL:url]
監(jiān)測用戶手機里到底裝沒裝某些應用砖瞧,來給用戶提示息堂。
但是也有一些別有用心的App ,這些App有一張常用 App 的"URL scheme"列表块促,他們會多次調(diào)用
[[UIApplication sharedApplication] canOpenURL:url]
遍歷該表荣堰,來監(jiān)測用戶手機都裝了什么 App 。
比如:"你"裝了叫“大姨媽”的App竭翠,他就可以知道"你"是女性振坚,他就可以只推給"你"女性用品的廣告。
這是屬于侵犯用戶隱私的行為斋扰,可能就是導致蘋果推出白名單的原因屡拨。
3、界面褥实、演示及代碼:
3.1、界面:
首先看一下A應用的界面:
5裂允、A_UI.png
5.1损离、A_cancel.png
5.2、A_comfirm.png
B應用的界面為:
6.1绝编、B_UI_1.png
6.2僻澎、B_UI_2.png
6.3貌踏、B_UI_3.png
3.2、演示圖如下:
demo.gif
3.3窟勃、代碼:
A:
在A應用的
Appdelegate.m
中祖乳,代碼如下:
#import "AppDelegate.h"
#import "ViewController.h"
#import "SecondViewController.h"
#import "ThirdViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
self.window.backgroundColor = [UIColor whiteColor];
UINavigationController *rootNav = [[UINavigationController alloc]initWithRootViewController:[[ViewController alloc] init]];
self.window.rootViewController = rootNav;
[self.window makeKeyAndVisible];
return YES;
}
// 過期
- (BOOL)application:(UIApplication *)application handleOpenURL: (NSURL *)url
{
NSLog(@"application.1 == %@",application);
NSLog(@"url.1 == %@",url);
return YES;
}
// 過期
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
NSLog(@"application.2 == %@",application);
NSLog(@"url.2 == %@",url);
NSLog(@"sourceApplication.2 == %@",sourceApplication);
return YES;
}
// NOTE: 9.0以后使用新API接口
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
// 1.獲取通過哪一個URL打開我的應用程序
NSString *urlStr = url.absoluteString;
// 2.取出window的根控制器
UINavigationController *rootNav = (UINavigationController *)[UIApplication sharedApplication].keyWindow.rootViewController;
// 首先回到根控制器
[rootNav popToRootViewControllerAnimated:NO];
// 3.取出MainViewController,使用主要控制器就可以跳轉到另外兩個控制器
ViewController *rootVc = rootNav.childViewControllers.firstObject;
if ([urlStr containsString:@"confirm"])
{
// 確定界面
SecondViewController *viewCon = [[SecondViewController alloc] init];
[rootVc.navigationController pushViewController:viewCon animated:YES];
}
else if ([urlStr containsString:@"cancel"])
{
// 取消界面
ThirdViewController *viewCon = [[ThirdViewController alloc] init];
[rootVc.navigationController pushViewController:viewCon animated:YES];
}
return YES;
}
@end
在A應用的ViewController.m
中,代碼如下:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"項目A";
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
[button setTitle:@"跳轉B應用" forState:UIControlStateNormal];
[self.view addSubview:button];
button.frame = CGRectMake(0, 0, 100, 20);
button.center = CGPointMake(self.view.frame.size.width/2, 100);
[button addTarget:self action:@selector(jump:) forControlEvents:UIControlEventTouchUpInside];
UIButton *buttonTwo = [UIButton buttonWithType:UIButtonTypeSystem];
[buttonTwo setTitle:@"跳轉B界面二" forState:UIControlStateNormal];
[self.view addSubview:buttonTwo];
buttonTwo.frame = CGRectMake(0, 0, 100, 20);
buttonTwo.center = CGPointMake(self.view.frame.size.width/2, 160);
[buttonTwo addTarget:self action:@selector(jumpViewTwo:) forControlEvents:UIControlEventTouchUpInside];
UIButton *buttonThree = [UIButton buttonWithType:UIButtonTypeSystem];
[buttonThree setTitle:@"跳轉B界面三" forState:UIControlStateNormal];
[self.view addSubview:buttonThree];
buttonThree.frame = CGRectMake(0, 0, 100, 20);
buttonThree.center = CGPointMake(self.view.frame.size.width/2, 220);
[buttonThree addTarget:self action:@selector(jumpViewThree:) forControlEvents:UIControlEventTouchUpInside];
}
// 直接跳轉B應用
- (void)jump:(UIButton *)button
{
NSURL *url = [NSURL URLWithString:@"ObjectB://"];
if ([[UIApplication sharedApplication] canOpenURL:url])
{
[[UIApplication sharedApplication] openURL:url];
}
}
// 跳轉B應用界面二
- (void)jumpViewTwo:(UIButton *)button
{
// 注意:這里將應用A的URL當做參數(shù)傳給應用B
NSURL *url = [NSURL URLWithString:@"ObjectB://session?ObjectA"];
if ([[UIApplication sharedApplication] canOpenURL:url])
{
[[UIApplication sharedApplication] openURL:url];
}
}
// 跳轉B應用界面三
- (void)jumpViewThree:(UIButton *)button
{
// 注意:這里將應用A的URL當做參數(shù)傳給應用B
NSURL *url = [NSURL URLWithString:@"ObjectB://timeLine?ObjectA"];
if ([[UIApplication sharedApplication] canOpenURL:url])
{
[[UIApplication sharedApplication] openURL:url];
}
}
@end
B:
應用B在Appdelagate.m
中秉氧,代碼如下:
#import "AppDelegate.h"
#import "ViewController.h"
#import "SecondViewController.h"
#import "ThirdViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
self.window.backgroundColor = [UIColor whiteColor];
UINavigationController *rootNav = [[UINavigationController alloc]initWithRootViewController:[[ViewController alloc] init]];
self.window.rootViewController = rootNav;
[self.window makeKeyAndVisible];
return YES;
}
- (BOOL)application:(UIApplication *)application handleOpenURL: (NSURL *)url
{
NSLog(@"application.1 == %@",application);
NSLog(@"url.1 == %@",url);
return YES;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
NSLog(@"application.2 == %@",application);
NSLog(@"url.2 == %@",url);
NSLog(@"sourceApplication.2 == %@",sourceApplication);
return YES;
}
// NOTE: 9.0以后使用新API接口
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
// 1.獲取通過哪一個URL打開我的應用程序
NSString *urlStr = url.absoluteString;
// 2.取出window的根控制器
UINavigationController *rootNav = (UINavigationController *)[UIApplication sharedApplication].keyWindow.rootViewController;
// 首先回到根控制器
[rootNav popToRootViewControllerAnimated:NO];
// 3.取出MainViewController,使用主要控制器就可以跳轉到另外兩個控制器
ViewController *rootVc = rootNav.childViewControllers.firstObject;
if ([urlStr containsString:@"session"])
{
// 界面二
SecondViewController *viewCon = [[SecondViewController alloc] init];
viewCon.urlPath =urlStr;
[rootVc.navigationController pushViewController:viewCon animated:YES];
}
else if ([urlStr containsString:@"timeLine"])
{
// 界面三
ThirdViewController *viewCon = [[ThirdViewController alloc] init];
viewCon.urlPath =urlStr;
[rootVc.navigationController pushViewController:viewCon animated:YES];
}
return YES;
}
@end
應用B在界面二(SecondViewController)
與界面三(ThirdViewController)
中代碼相同眷昆,所以下面只列出界面二(SecondViewController)
的代碼,如下:
#import "SecondViewController.h"
@interface SecondViewController ()
@end
@implementation SecondViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"界面二";
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"取消" style:UIBarButtonItemStylePlain target:self action:@selector(clickLeftButton)];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"確定" style:UIBarButtonItemStylePlain target:self action:@selector(clickRightButton)];
}
- (void)clickLeftButton
{
// 截取字符串,拿到scheme
NSInteger location = [self.urlPath rangeOfString:@"?"].location;
NSString *scheme = [self.urlPath substringFromIndex:location + 1];
// 通過scheme返回項目A
NSString *news = [NSString stringWithFormat:@"%@://cancel", scheme];
NSURL *newsUrl = [NSURL URLWithString:news];
if ([[UIApplication sharedApplication] canOpenURL:newsUrl])
{
[[UIApplication sharedApplication] openURL:newsUrl];
}
}
- (void)clickRightButton
{
// 截取字符串,拿到scheme
NSInteger location = [self.urlPath rangeOfString:@"?"].location;
NSString *scheme = [self.urlPath substringFromIndex:location + 1];
// 通過scheme返回項目A
NSString *news = [NSString stringWithFormat:@"%@://confirm", scheme];
NSURL *newsUrl = [NSURL URLWithString:news];
if ([[UIApplication sharedApplication] canOpenURL:newsUrl])
{
[[UIApplication sharedApplication] openURL:newsUrl];
}
}
@end
4汁咏、總結:
本篇文章亚斋,只是技術實現(xiàn)上的簡單演示。
在實際的應用中攘滩,應用間的跳轉要遠比這個復雜很多帅刊,也嚴謹很多。
但是其實現(xiàn)的原理漂问,也只是在這個原理基礎上更加復雜的擴展而已赖瞒,所以,希望這里對大家有所幫助蚤假。
5栏饮、參考文獻:
1、http://www.reibang.com/p/732c5e1720d0
2勤哗、http://lidaoliang.com/14429923363009.html
3抡爹、http://www.reibang.com/p/545014e51ad5