iOS中使用URL Scheme进行App跳转的教程
url scheme的作用
我们都知道苹果手机中的app都有一个沙盒,app就是一个信息孤岛,相互是不可以进行通信的。但是ios的app可以注册自己的url scheme,url scheme是为方便app之间互相调用而设计的。我们可以通过系统的openurl来打开该app,并可以传递一些参数。
例如:你在safari里输入www.alipay.com,就可以直接打开你的支付宝app,前提是你的手机装了支付宝。如果你没有装支付宝,应该显示的是支付宝下载界面,点击会跳到appstore的支付宝下载界面。
url scheme必须能唯一标识一个app,如果你设置的url scheme与别的app的url scheme冲突时,你的app不一定会被启动起来。因为当你的app在安装的时候,系统里面已经注册了你的url scheme。
一般情况下,是会调用先安装的app。但是ios的系统app的url scheme肯定是最高的。所以我们定义url scheme的时候,尽量避开系统app已经定义过的url scheme。
注册url scheme
1.在info.plist里添加url types
每一个项目里面都会有一个info.plist配置文件。找到info.plist,右键选择add row,然后选择url types。如图所示:
2.添加url schemes
添加完url types,点击展开。右键选择add row,添加url schemes:
3.设置url schemes
设置url schemes为iosdevtip
4.设置url identifier
url identifier是自定义的 url scheme 的名字,一般采用反转域名的方法保证该名字的唯一性,比如 com.iosstrongdemo.www
添加成功启动提示
为了方便测试,我们在appdelegate里面添加一个uialertview,当app被成功打开时,会提出提示:
- (bool)application:(uiapplication *)application handleopenurl:(nsurl*)url
{
// 接受传过来的参数
nsstring *text = [[url host] stringbyreplacingpercentescapesusingencoding:nsutf8stringencoding];
uialertview *alertview = [[uialertview alloc] initwithtitle:@"打开啦"
message:text
delegate:nil
cancelbuttontitle:@"ok"
otherbuttontitles:nil];
[alertview show];
return yes;
}
safari启动自定义的url schemes app
既然已经配置好url schemes,那么我们可以来款速测试一下,我们设置的url schemes是否有效。打开safari,在地址栏里输入:iosdevtip://
果然成功打开:
也可以在地址栏中输入:iosdevtip://com.iosstrongdemo.www。也是可以打开注册了url schemes的app的。
通过另一个app启动注册了url schemes的app
nsstring *url = @"iosdevtip://";
// nsstring *url = @"iosdevtip://com.iosstrongdemo.www";
if ([[uiapplication sharedapplication]
canopenurl:[nsurl urlwithstring:url]])
{
[[uiapplication sharedapplication] openurl:[nsurl urlwithstring:url]];
}
else
{
nslog(@"can not open url scheme iosdevtip");
}
打开注册iosdevtip的app格式为: url scheme://url identifier,直接调用url scheme也可打开程序, url identifier是可选的。
通过注册的url scheme向目标app传递参数
通过url scheme启动app很简单就可以做到,但有时候我们想在启动app的时候传递一些参数,这个时候我们就可以通过url scheme自定义url来传递参数了。
昨天我们在appdelegate调用了uiapplicationdelegate的代理方法:
- (bool)application:(uiapplication *)application handleopenurl:(nsurl*)url
{
// 接受传过来的参数
nsstring *text = [[url host] stringbyreplacingpercentescapesusingencoding:nsutf8stringencoding];
uialertview *alertview = [[uialertview alloc] initwithtitle:@"打开啦"
message:text
delegate:nil
cancelbuttontitle:@"ok"
otherbuttontitles:nil];
[alertview show];
return yes;
}
我们来看看苹果给这个方法的注释:
- (bool)application:(uiapplication *)application handleopenurl:(nsurl *)url; // will be deprecated at some point, please replace with application:openurl:sourceapplication:annotation:
这个方法在未来将被废弃,可以用application:openurl:sourceapplication:annotation:来代替。
url传参格式
昨天我们在iosstrongdemo注册的url scheme还记得是什么吗?你应该还有印象的就是ios开发的id:iosdevtip。
假设我们想要传递两个参数分别是名字name和手机号phone,格式如下:
iosdevtip://?name=ligang&phone=13888888888
有没有似曾相识的感觉。我们用get方式请求一个接口是不是就是这样的。
被启动的app处理传过来的参数
- (bool)application:(uiapplication *)application
openurl:(nsurl *)url
sourceapplication:(nsstring *)sourceapplication
annotation:(id)annotation
{
nslog(@"sourceapplication: %@", sourceapplication);
nslog(@"url scheme:%@", [url scheme]);
nslog(@"url query: %@", [url query]);
// 接受传过来的参数
uialertview *alertview = [[uialertview alloc] initwithtitle:@"打开啦"
message:[url query]
delegate:nil
cancelbuttontitle:@"ok"
otherbuttontitles:nil];
[alertview show];
return yes;
}
当app被启动是,会调用代理方法application:openurl:sourceapplication:annotation:。参数url就是启动app的url,参数sourceapplication就是来源app的bundle id。
我们依然通过safari来测试,在safari的地址栏中输入:iosdevtip://?name=ligang&phone=13888888888
即可打开app,看看参数是否传递过来:
最后我们看一下打印:
2015-07-15 22:38:25.655 iosstrongdemo[9983:2894855] sourceapplication: com.apple.mobilesafari 2015-07-15 22:38:28.664 iosstrongdemo[9983:2894855] url scheme:iosdevtip 2015-07-15 22:38:28.665 iosstrongdemo[9983:2894855] url query: name=ligang&phone=13888888888
sourceapplication打印出来是com.apple.mobilesafari,从这里可以看出来,是从safari启动我们的app的。
我们虽然自定义了url scheme,但是我们不能阻止别人通过自定义的url scheme来打开我们的应用。怎么解决呢?
我们可以指定相应的sourceapplication,也就是相应的bundle id,通过bundle id来决定是否可以打开我们的app:
- (bool)application:(uiapplication *)application
openurl:(nsurl *)url
sourceapplication:(nsstring *)sourceapplication
annotation:(id)annotation
{
nslog(@"sourceapplication: %@", sourceapplication);
nslog(@"url scheme:%@", [url scheme]);
nslog(@"url query: %@", [url query]);
if ([sourceapplication isequaltostring:@"com.3sixty.callcustomurl"]){
// 接受传过来的参数
uialertview *alertview = [[uialertview alloc] initwithtitle:@"打开啦"
message:[url query]
delegate:nil
cancelbuttontitle:@"ok"
otherbuttontitles:nil];
[alertview show];
return yes;
}else{
return no;
}
}
这样我们就可以通过bundle id来决定是否允许打开我们的app。