在ios中,软件的调用是通过项目设置中的URL Schemes来调用的。
一、比较常用的调用
这几个是比较常用的调用,是系统方法支持的
//调用 自带mail
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"mailto://hudong567@qq.com"]];
//调用 电话phone
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://10086"]];
//调用 SMS
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms://10086"]];
//调用自带 浏览器 safari
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.baidu.com"]];
//调用 Remote
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"remote://fff"]];
这些是系统基础的,不需要修改什么,只要调用对应的内容即可
1、测试demo,要真机调试才可以
static int i =0;
- (void)viewDidLoad {
[super viewDidLoad];
UIButton * button = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[button setTitle:@"test" forState:UIControlStateNormal];
[button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
[button addTarget:self action:@selector(test) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
-(void)test{
if (i == 0) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"mailto://hudong567@qq.com"]];
}
if (i == 1) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://10086"]];
}
if (i == 2) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms://10086"]];
}
if (i == 3) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.baidu.com"]];
}
if (i == 4) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"remote://fff"]];
}
i++;
}
二、用户软件之间的调用
软件的调用这里用Demo说明。
Demo下载地址:
github:https://github.com/DamonHu/HudongBlogDemo/tree/master/shemedemon
这里app1是被唤醒的,app2是去调用app1的
首先在app1的项目设置里面info选项的URL types里面填写一个自定义的schemes,这个schemes是用来被调用的时候系统知道需要调用哪个软件的,所以要有唯一性。
这里我设置成了damon,你们可以自定义
然后在app1中的AppDelegate.m文件里面增加这个函数
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation
这个函数只有在其他软件调用它的时候才会被调用,所以我这里代码设置下,让其他软件调用的时候显示出来调用的内容,如果实用运用中,只要判断url的正确性,然后return yes就行了。我这里是为了实验,首先获取当前显示的viewcontroller,然后再加上一个label显示调用的内容
- (UIViewController *)getCurrentVC
{
UIViewController *result = nil;
UIWindow * window = [[UIApplication sharedApplication] keyWindow];
if (window.windowLevel != UIWindowLevelNormal)
{
NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow * tmpWin in windows)
{
if (tmpWin.windowLevel == UIWindowLevelNormal)
{
window = tmpWin;
break;
}
}
}
UIView *frontView = [[window subviews] objectAtIndex:0];
id nextResponder = [frontView nextResponder];
if ([nextResponder isKindOfClass:[UIViewController class]])
result = nextResponder;
else
result = window.rootViewController;
return result;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation
{
// NSLog(@"application bundle id:%@",sourceApplication);
// NSLog(@"url scheme:%@",[url scheme]);
// NSLog(@"url query:%@",[url query]);
UILabel *sssslable = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 460, 260)];
[sssslable setNumberOfLines:3];
[sssslable setTextColor:[UIColor redColor]];
[sssslable setText:[NSString stringWithFormat:@"bundle id:%@,url scheme:%@,urlpar:%@,",sourceApplication,[url scheme],url]];
[[self getCurrentVC].view addSubview:sssslable];
return YES;
}
这样app1就已经设置完毕了,现在再建立一个app2的工程。
因为现在ios9对软件的安全性提高了,所以需要先设置app2的info.plist文件,加上一个LSApplicationQueriesSchemes的array字段,下面加上app1中设置的damon,
否则在使用的时候会报错
-canOpenURL: failed for URL: "OpenAppTest://markid=007" - error: "This app is not allowed to query for scheme
这就是为什么接微信和新浪的时候也需要设置的原因。
2016.10.8增加对OpenURL和canOpenURL说明start
在info.plist文件里面添加LSApplicationQueriesSchemes字段,是在需要调用canOpenURL这个函数的话需要加上,如果仅仅是直接调用OpenURL的话,可以不用加,如果调用canOpenURL这个函数,而info.plist文件里面没有加上对应的url,那么即使用户手机上安装了那个软件,canOpenURL依然返回的为false。
如这个文章http://awkwardhare.com/post/121196006730/quick-take-on-ios-9-url-scheme-changes所说:
If you call the “canOpenURL” method on a URL that is not in your whitelist, it will return “NO”, even if there is an app installed that has registered to handle this scheme. A “This app is not allowed to query for scheme xxx” syslog entry will appear.
原因是因为canOpenURL和OpenURL的区别在于canOpenURL是在静默状态下判断对应的软件是否安装,而OpenURL则是直接去调用该软件,也许出于安全性原因,如果不对canOpenURL做限制,那么就可能会有软件不是去调用其他软件,而是专门的扫描用户手机里面是否安装了其他对应的app但是用户却没有察觉,而openURL就不同了,只要调用了,就会去打开对应的app软件,这样用户就知道了某个软件在后台干嘛,所以对于canOpenURL必须要在info.plist加列表,而OpenURL可以不用加,并且info.plist不能动态修改,并且白名单的上限是50个。
正如在《ios9适配 跳转白名单设置?》中的回答
LSApplicationQueriesSchemes 这个东西你搞错了一个概念,他不是决定 openURL 的,是决定 canOpenURL 的。
所以说你要跳转的 app 完全不用加到 LSApplicationQueriesSchemes 里面去,如果你要判断一个 app 是否安装,才需要加进去。
Bundle 里面的 Plist 是不可能改的。
但是测试了下,程序在后台运行的话,canOpenUrl在满足条件时会立马变为true,而openURL只有在这个app是当前运行状态下,才可以去调用其他的app
end
设置好之后,就可以调用了,在app2的view中写一个调用函数,这样就可以直接调用app1了。
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 30, 70, 70)];
[button setTitle:@"唤醒app" forState:UIControlStateNormal];
[button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
[button addTarget:self action:@selector(awakeother) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
-(void)awakeother
{
NSLog(@"唤醒app");
NSString * url = @"damon://ssss";
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:url]]) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
}
}
设置好之后,先运行app1,确保app1安装在模拟器上,然后再安装app2,确保两个是安装在同一个模拟器上面
然后运行app2即可看到效果如下
这就是app2调用app1的过程。
三、用户软件之间的回调
除了app2调用app1,调用之后想回去app2中,就是app1返回去再调用app2可以这么做:
因为只要是以damon://开头的,都可以调用起app1,所以这里可以在app2调用app1的时候传入app2自己的url schemes当参数,这样就可以在app1的回调函数中得到app2的schemes了,然后同样的方法调用app2的即可。这个参数的说明看下面这个url的说明。
四、URL的说明
上面输出的是整个url的,没有截取,所以说一下url的格式
调用函数
NSString *ll = @"damon://sdfmmmmss";
NSURL * uu = [NSURL URLWithString:ll];
NSLog(@"uu:%@n",uu);
NSLog(@"scheme:%@n",[uu scheme]);
NSLog(@"host:%@n",[uu host]);
NSLog(@"query:%@n",[uu query]);
NSLog(@"%@n",[uu relativeString]);
输出内容
所以可以看出
scheme就是前面写的damon
host就是直接跟着damon://后面的,截至到第一个的内容
query则是第一个之后的内容
这里根据需要截取即可。
五、参考文章
最后感谢下面几个文章:
- iOS App 唤醒另一个App
- IOS-应用之间调用
- 【Launcher 教程】从 URL Schemes 入门到用 Launcher 调用各效率软件
- iOS9适配 之 关于info.plist 第三方登录 添加URL Schemes白名单
- https://github.com/ChenYilong/iOS9AdaptationTips
版权属于:东哥笔记 - DongGe.org
本文链接:https://dongge.org/blog/313.html
自2017年12月26日起,『转载以及大段采集进行后续编辑』须注明本文标题和链接!否则禁止所有转载和采集行为!