iOS中使用URL Scheme进行App跳转的教程

时间:2021-12-16 02:47:05

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。如图所示:

iOS中使用URL Scheme进行App跳转的教程

2.添加url schemes

添加完url types,点击展开。右键选择add row,添加url schemes:
iOS中使用URL Scheme进行App跳转的教程
3.设置url schemes

设置url schemes为iosdevtip

iOS中使用URL Scheme进行App跳转的教程

4.设置url identifier

url identifier是自定义的 url scheme 的名字,一般采用反转域名的方法保证该名字的唯一性,比如 com.iosstrongdemo.www

iOS中使用URL Scheme进行App跳转的教程

添加成功启动提示

为了方便测试,我们在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://

iOS中使用URL Scheme进行App跳转的教程

果然成功打开:

iOS中使用URL Scheme进行App跳转的教程

也可以在地址栏中输入: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,格式如下:

?
1
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

iOS中使用URL Scheme进行App跳转的教程

即可打开app,看看参数是否传递过来:

iOS中使用URL Scheme进行App跳转的教程

最后我们看一下打印:

?
1
2
3
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。