iOS 应用之间的跳转(OC&Swift)

栏目: Swift · 发布时间: 5年前

内容简介:一、应用间跳转介绍1.1、什么是应用间跳转,有什么作用? 如下<1>、使用第三方用户登录,需要用户授权,还需要"返回到调用的程序,同时返回授权的用户名"

一、应用间跳转介绍

1.1、什么是应用间跳转,有什么作用? 如下

<1>、使用第三方用户登录,需要用户授权,还需要"返回到调用的程序,同时返回授权的用户名"

<2>、应用程序推广,设置-推荐应用-有很多应用程序图标如果本机已经安装过,会直接跳转到另外一个应用程序, 软件的广告,我们在抖音或者进入头条都可以看到很多的点击事件进去其他的app或者去下载appstore下载app

<3>、平时 支付宝,微信支付 等等

1.2、如何实现应用程序间跳转 ?

<1>、跳转appstore进入自己的app: 在我们自己的app里面有时候我们会有更新提醒,其实也就是打开我们自己 app 的 url,以 itms-apps://或https://开头的应用详情页链接,跳转到AppStore,如下,其中url要进行转码,下面我就不再转码了

OC 版本:

NSURL *url = [NSURL URLWithString:@"itms-apps://itunes.apple.com/app/id1129144823"];

// 注意: 跳转之前, 可以使用 canOpenURL: 判断是否可以跳转
if (![[UIApplication sharedApplication]canOpenURL:url]) {
        // 不能跳转就不要往下执行了
        return;
}

if (@available(iOS 10.0, *)){

      [[UIApplication sharedApplication]openURL:url options:@{UIApplicationOpenURLOptionsSourceApplicationKey:@YES} completionHandler:^(BOOL success) {
  
            if (success) {
                 NSLog(@"10以后可以跳转url");
            }else{
                NSLog(@"10以后不可以跳转url");
            }
      }];
 }else{
 
     BOOL success = [[UIApplication sharedApplication]openURL:url];
     if (success) {
         NSLog(@"10以前可以跳转url");
     }else{
         NSLog(@"10以前不可以跳转url");
     }
}

Swift 版本:

let url = URL(string: "itms-apps://itunes.apple.com/app/id1129144823")

// 注意: 跳转之前, 可以使用 canOpenURL: 判断是否可以跳转
if !UIApplication.shared.canOpenURL(url!) {
     // 不能跳转就不要往下执行了
     return
}

if #available(iOS 10.0, *) {
  
      UIApplication.shared.open(url!, options: [:]) { (success) in
           if (success) {
                print("10以后可以跳转url")
           }else{
                print("10以后不能完成跳转")
           }
       }
} else {
       // Fallback on earlier versions
       let success = UIApplication.shared.openURL(url!)
       if (success) {
             print("10以下可以跳转")
       }else{
             print("10以下不能完成跳转")
       }
 }

<2>、打电话:tel://电话号码,代码和上面的一样

<3>、发短信:sms://电话号码,代码和上面的一样

<4>、发邮件:mailTo://邮箱号,代码和上面的一样

提示:itms-apps、https、tel、sms、mailTo 都是协议,app之间跳转的协议是:Scheme,如果想要跳转到不同app,就要打开对应的 URL(协议是:scheme), scheme是一个具体的字符串,并不是scheme这几个字母,在下面会详细的介绍

1.3、URL : 统一资源定位符

<1>、我们以淘宝网的一个链接为例:https://www.taobao.com/markets/bao/xiangbao?spm=a21bo.2017.201867-main.5.5af911d9blzLlJ

Swift版本

let url = URL(string: "https://www.taobao.com/markets/bao/xiangbao?spm=a21bo.2017.201867-main.5.5af911d9blzLlJ")
print("协议=",url!.scheme ?? "","IP或者是域名=",url!.host ?? "","路径=",url!.path ,"参数=",url!.query ?? "")

打印结果:协议= https IP或者是域名= www.taobao.com 路径= /markets/bao/xiangbao 参数= spm=a21bo.2017.201867-main.5.5af911d9blzLlJ

OC版本

NSURL *url = [NSURL URLWithString:@"https://www.taobao.com/markets/bao/xiangbao?spm=a21bo.2017.201867-main.5.5af911d9blzLlJ"];
NSLog(@"协议=%@ IP或者是域名=%@ 路径=%@ 参数=%@",url.scheme,url.host,url.path,url.query);

打印结果和上面的一样

<2>、一个 url 分为以下部分

协议:https
IP或者是域名:www.taobao.com
路径:/markets/bao/xiangbao
参数:spm=a21bo.2017.201867-main.5.5af911d9blzLlJ

二、应用间跳转实现

2.1、我们先以自己创建的app实现来回的跳转:Test1 与 Test2 两个项目

2.2、给Test2项目设置一个 URL Scheme,用来其他的app跳转到 Test2

iOS 应用之间的跳转(OC&Swift)

给Test2项目设置一个 `URL Scheme`,用来其他的app跳转到 `Test2`

提示:设置 URL Scheme时, 不要加 ://,比如上面直接设置:test2 一个字符串就好

  • 再说一下不一定根据 URL Scheme进入不同的界面的,也可以在Scheme后拼接参数,比如:test2://1234

  • URL scheme 的作用:我们可以将应用“绑定”到一个自定义 URL scheme 上,该 scheme 用于从浏览器或其他应用中启动本应用,同时跳转时也可以传递参数。比如,可以在网页上添加一个链接,点击这个链接后会自动打开对应的APP上。或者从一个 APP 跳转到另一个 APP,用的也是 URL scheme。比如微博或者微信的登录或者分享之类的。在选择登录时就会跳到微信或者微博里,等登录了以后就可以跳转回去。

2.3、在Test1项目里面设置白名单

<1>、解释一下什么是白名单:其实白名单是在 iOS9.0 以后提出的,它就是一个数组,里面放的是其他app的URL Scheme名字,在iOS9以前是不需要设置的,可以直接用canOpenURL判断是否可以跳转,但是在iOS9.0之后如果不添加白名单, openURL 是无法判断判断是否可以跳转的。

提示:不想添加白名单是可以的,其他的app分享到微信,它确信你的app存在,就不需要在白名单添其他app的URL Scheme,也就是不需要使用 canOpenURL判断是否可以跳转 是否可以跳转

<2>、设置白名单,如果你要跳转其他的app,就要在自己的app的 info.plist 设置白名单,添加其他app的URL Scheme,白名单的字段是:LSApplicationQueriesSchemes,下面我们在 Test1添加白名单

iOS 应用之间的跳转(OC&Swift)

白名单的设置

2.4、在Test1项目跳转到Test2项目测试,代码如下

我们把上面 1.2中的<1>里面的url换为下面,在同一个手机上运行 Test1 和 Test2 两个项目

iOS 应用之间的跳转(OC&Swift)

跳转效果

OC 版本:后面的代码都是  1.2中的<1>里面的代码

NSURL *url = [NSURL URLWithString:@"test2://"];
// 注意: 跳转之前, 可以使用 canOpenURL: 判断是否可以跳转
if (![[UIApplication sharedApplication]canOpenURL:url]) {
     // 不能跳转就不要往下执行了
     return;
}
------后面的代码都是  1.2中的里面的代码

Swift 版本:后面的代码都是  1.2中的<1>里面的代码

let url = URL(string: "test2://")
// 注意: 跳转之前, 可以使用 canOpenURL: 判断是否可以
if !UIApplication.shared.canOpenURL(url!) {
    // 不能跳转就不要往下执行了
    return
}
-----后面的代码都是  1.2中的里面的代码

拓展:看到上面效果,我们就简单的完成了app之间的跳转,这也是一些三方在分享的时候要求我们app设置白名单,你要分享到哪些平台,你就要添加其他平台的 URL Scheme,这个不是随便填写的,其他平台设置的URL Scheme是什么,就在白名单就要添加什么,可不是自己随意写的

2.5、如果你想在Test2app再返回到Test1app,其实也就是反过来,在 Test2 的白名单里面添加Test1的URL Scheme,在跳转Test1的使用根据Test1的schmem用openURL返回,记得先用 canOpenURL判断一下

提示:在做分享的时候我们会检测微信是不是安装了,跳到微信后把微信给的URL Scheme也带了过去,在从微信返回的时候不用再判断 自己的app是否安装了,直接用OpenURL返回即可,添加白名单的目的是为了检测其他的app是否安装,可不可以跳转;在自己的app跳转其他的app的一定要用canOpenURL检测一下,微信不在白名单添加其他app的URL Scheme的原因是它确信你的app存在,不需要用canOpenURL判断

2.6、常用白名单字段(更多的白名单字段在 mob平台iOS开发文档查看 )

新浪

sinaweibo,
sinaweibohd,
sinaweibosso,
sinaweibohdsso,
weibosdk,
weibosdk2.5

微信

wechat,
weixin

支付宝

alipay,
alipayshare

QQ

mqqOpensdkSSoLogin,
mqqopensdkapiV2,
mqqopensdkapiV3,
wtloginmqq2,
mqq,
mqqapi
timapi

提示:微信,新浪,QQ它们设置很多的Scheme的原因是要根据这些不同的Scheme做什么操作,比如根据Scheme跳转到不同的界面等等

三、怎样跳转到不同界面?

3.1、再建立一个项目 Test3 ,给它添加一个 URL Scheme,再给Test3添加两个控制器 ViewController2与ViewController3

iOS 应用之间的跳转(OC&Swift)

再建立一个项目Test3,给它添加一个Url Scheme

提示: 一个项目可以添加多个 URL Scheme,举个例子,你在用支付宝支付,支付宝会给你一个 URL Scheme字符串,让你添加到自己URL Types 里面,到时候你在调用支付宝支付,在支付宝界面返回的时候用这个支付宝给你的 URL Scheme 返回;同样,微信也会给你一个URL Scheme字符串,当你跳转到微信里面,微信里面根据微信给你的URL Scheme返回到你的app;

  • 再解释一下:为什么微信或者支付宝会给一个唯一的URL Scheme字符串,其目的是为了防止,从他们的应用返回到自己的应用时出错,根据URL Scheme字符串返回到自己的app的,如果手机里面有两个程序都有相同的一个 URL Scheme字符串,那么就出问题了,它就不知道返回哪个app了,其实如果遇到相同的URL Scheme,谁的app先安装的,就返回到谁的app,这个我测试了

3.2、在Test3处理其他Test1(或者其他的app通过openURL)进来的判断

OC 版本

// 即将过期,不建议使用(建议把这3个方法同时实现)
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    [self dealopenURL:url];
    return YES;
}

-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options{
    [self dealopenURL:url];
    return YES;
}

-(void)dealopenURL:(NSURL *)url{
    
    NSLog(@"协议=%@ IP或者是域名=%@ 路径=%@ 参数=%@",url.scheme,url.host,url.path,url.query);
    
    // 1.获取主控制器
    UINavigationController *rootNav = (UINavigationController *)self.window.rootViewController;
    // 拿到栈底的控制器
    ViewController *mainVc = [rootNav.childViewControllers firstObject];
    // 返回主控制器,防止多次进入错乱
    [rootNav popToRootViewControllerAnimated:NO];
    
    // 利用 URL : 统一资源定位符来判断
    if ([url.path isEqualToString:@"/vc2"]) {
    
         ViewController2 *vc2 = [ViewController2 new];
         vc2.urlString = url.host;
         [mainVc.navigationController pushViewController:vc2 animated:YES];
     } else if ([url.path isEqualToString:@"/vc3"]) {
  
         ViewController3 *vc3 = [ViewController3 new];
         vc3.urlString = url.host;
         [mainVc.navigationController pushViewController:vc3 animated:YES];
     }
}

Swift 版本

// 最新的
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
 
      dealopenURL(url: url as NSURL)
      return true
}

// 被遗弃的(最好两个都用)
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
 
      dealopenURL(url: url as NSURL)
      return true
}

// MARK:跳转的处理
func dealopenURL(url:NSURL){
 
      let nav: UINavigationController! = window?.rootViewController as? UINavigationController
 
      nav.popToRootViewController(animated: false)
 
      let rootVC = nav.children[0]
 
      if url.path == "/vc2" {
     
           let vc2 = ViewController2()
           vc2.urlString = url.host
           rootVC.navigationController?.pushViewController(vc2, animated: true)
     
       }else if url.path == "/vc3"{
     
           let vc3 = ViewController3()
           vc3.urlString = url.host
           rootVC.navigationController?.pushViewController(vc3, animated: true)
       }
 
}

提示:上面跳转是利用 URL的path(统一资源定位符)来判断,我是把 带过来的 URL Scheme 放到了 IP或者是域名 的位置

3.3、在Test1里面的跳转代码

OC 版本

// 跳转Test3的ViewController2
[self jumpUrl:@"test3://test1/vc2"];
// 跳转Test3的ViewController3
[self jumpUrl:@"test3://test1/vc3"];

-(void)jumpUrl:(NSString *)urlStr{

      NSURL *url = [NSURL URLWithString:urlStr];
      
      // 注意: 跳转之前, 可以使用 canOpenURL: 判断是否可以跳转
      if (![[UIApplication sharedApplication]canOpenURL:url]) {
            return;
      }
      
      if (@available(iOS 10.0, *)){
  
            [[UIApplication sharedApplication]openURL:url options:@{UIApplicationOpenURLOptionsSourceApplicationKey:@YES} completionHandler:^(BOOL success) {
      
                if (success) {
                        NSLog(@"10以后可以跳转url");
                }else{
                        NSLog(@"10以后不可以跳转url");
                }
            }];
       }else{
  
            BOOL success = [[UIApplication sharedApplication]openURL:url];
  
             if (success) {
                 NSLog(@"10以前可以跳转url");
             }else{
                NSLog(@"10以前不可以跳转url");
             }
        }
}

Swift 版本

jumpUrl(url: NSURL(string: "test3://test1/vc2")!)
jumpUrl(url: NSURL(string: "test3://test1/vc3")!)

func jumpUrl(url:NSURL){
 
     if !UIApplication.shared.canOpenURL(url as URL) {
          return
     }
 
     if #available(iOS 10.0, *) {
     
          UIApplication.shared.open(url as URL, options: [:]) { (success) in
         
              if (success) {
                   print("10以后可以跳转url")
              }else{
                   print("10以后不能完成跳转")
              }
          }
     } else {
     // Fallback on earlier versions
          let success = UIApplication.shared.openURL(url as URL)
          if (success) {
               print("10以下可以跳转")
          }else{
               print("10以下不能完成跳转")
          }
     }
}

四、总结

4.1、实现两个app之间跳转的步骤

<1>、在各自的app里面设置 URL scheme

<2>、在各自app的info.plist里面添加字段LSApplicationQueriesSchemes,类型为数组,数组中添加对方的 scheme 字符串(白名单的作用仅仅是iOS9.0方法canOpenURL要求的,因为我们在跳转前需要检查下设备有没有安装将要跳转的应用)

<3>、通过openURL 跳转对方的 URL Scheme 即可

4.2、在最后我重复一下很多app跳转到微信、支付宝、微博等等后,它们是怎么做到再回到我们的app的,首先我们知道这些app里面的白名单肯定是没有我们的 URL Scheme

答:首选我们在其他平台注册自己的应用的时候,都会给我们一个 URL Scheme 字符串,这个字符串我们需要添加到我们的 URL Scheme里面,想必大家也知道了,我们需要添加多个URL Scheme,因为微博,微信,支付宝都会给我们一个唯一的 URL Scheme 字符串,唯一是为了防止我们跳转到他们的app后再返回的时候出错,还有其他设备的 URL Scheme与我们的一样就会造成返回错乱的情况;再说支付宝微信在返回我们的app的时候他们不去白名单里面添加我们的 URL Scheme,那是因为他们知道我们的设备肯定有我们的app,不然怎么会进入到微信和支付宝的?又有人说了我先进到微信,在弹出返回自己app和留在微信的界面弹出,我进入后台去把自己的app卸载,再去微信点击返回自己的app,其实我也是这么测试的,但是只要离开微信,返回自己app和留在微信的按钮就会消失,所以微信返回其他的app是不需要在白名单添加其他app的 URL Scheme。

测试的demo

到此结束这篇文章,希望你能够通过这篇博客彻底知道 URL Scheme作用和白名单是什么以及如何跳转在app之间跳转。有不理解的地方写下你的评论,看到后我会第一时间回答。

作者:IIronMan

链接:https://www.jianshu.com/p/bbe298172152


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Don't Make Me Think

Don't Make Me Think

Steve Krug / New Riders Press / 18 August, 2005 / $35.00

Five years and more than 100,000 copies after it was first published, it's hard to imagine anyone working in Web design who hasn't read Steve Krug's "instant classic" on Web usability, but people are ......一起来看看 《Don't Make Me Think》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具