iOS 唤起APP之URL Scheme

什么是URL Scheme

简单的说,因为苹果选择使用沙盒机制来保障用户的隐私和安全,APP只能访问本身沙盒数据,但同时也阻碍了应用间合理的信息共享。所以苹果提供了一个能够在APP之间跳转的方法:URL Scheme。若是你的APP须要其余APP访问某些功能或者数据,那么你须要在你的APP定义一个相应的URL Scheme。当别的APP使用URL Scheme进行访问时,系统会根据URL Scheme进行匹配,从而来拉起对应的APP。html

如何理解URL Scheme

若是想要更清晰的认识URL Scheme电话,咱们须要了解下面几个概念:web

  1. URL(Uniform Resource Locator:统一资源定位器):也就是咱们所属于的"网址",经过它咱们能够访问到咱们想要的服务和资源,而且URL也能够传递相应的参数,也就是咱们常说的GET请求;
  2. URL地址格式排列为:scheme://host:port/path,举个栗子:https://www.jianshu.com/u/b09c13696e1c就是个典型的URL,而这个网址对应的Scheme就是https,标识的是一个URL中的一个位置——最初始的位置,也能够理解为一种协议头。而咱们自定义的URL Scheme能够理解为一种自定义的协议。
  3. 根据咱们上面对URL Scheme的理解,咱们能够很轻易地理解,在以本地应用为主的iOS上,咱们能够像定位一个网页同样,用一种特殊的URL来定位一个应用甚至应用里某个具体的功能。而定位这个应用的标识,也就是Scheme。好比微信的Schemeweixin,打开微信扫一扫功能的URL Scheme则是weixin://dl/scan

这样一对比就容易很明白的理解出了URL Scheme的真正含义,它是为了在iOS系统中定位对应的App而后执行对应的操做,复杂的URL Scheme还能够传递参数。安全

URL Scheme的应用场景

  1. 使用iOS系统预设的URL Scheme调用系统APP:iOS系统内置的App,如mail,电话等等,都有相应的URL Scheme供其余的APP调用。好比下面的代码就是使用系统的电话APP给18888888888打电话。
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://18888888888"]];如下是一些URL Scheme合集:
  1. 使用URL Scheme让别的应用打开当前APP,本身的APP写好一下可让其余APP来使用的功能,或者当前APP使用其余APP提供的服务。好比支付宝,当APP使用支付宝支付是,就可使用支付宝定义好的Scheme来访问支付宝支付功能。由于URL能够携带一些参数所以咱们也能够进行一些数据的共享。
  2. web页面经过URL Scheme来使用APP的一些功能。web能够经过window.location.href跳转方式跳转对应的URL Scheme从而来使用APP中一些功能。相对比较经常使用的URL Scheme的应用场景。
  3. 进行App内页面跳转。在传统意义上的页面跳转,无非也就是如下几种方式:
    • Storyboard的segues方式跳转
    • 直接跳转present,dismiss跳转
    • UINavigationController的push,pop跳转
    这些方式其实都有一个缺点,那就是跳转很不灵活,若是想让一个模块根据需求动态的跳转不一样页面,传递不一样的参数,那么就必须书写不少复杂的逻辑几句一些状况也选择要跳转的逻辑。
    或许你说我能够经过控制器的名字来建立对应的控制器进行动态的跳转,但事实上这样的方式若是仅仅进行跳转仍是能知足需求的,可是在传递参数方面就是闲的力不从心。

因此说了那么多,有一种跳转方式能够既知足跳转的动态需求,也能够灵活的传递参数。这种方式就是使用URL Scheme进行动态跳转。这也是我很是推荐的一种使用方式。而且在一些组件化开发的尝试中,这种跳转方式也带来了不少便利。服务器

使用URL Scheme跳转的好处

  1. URL Scheme跳转方式比较灵活,只须要本地进行简单逻辑处理,使用openURL来打开对应的控制器,而这个你想要打开的URL Scheme是能够动态的从服务器动态获取的。那么这样就很简单的实现了动态跳转。
  2. URL Scheme传递参数的方式也与URL一致,只须要简单的在URL里附加上对应的参数便可。
  3. 这种页面跳转是无差异的,经过URL Scheme跳转能够无缝的在H5页面和原生页面之间跳转传值,而无需作更多的逻辑判断。

使用URL Scheme跳转的缺点

  1. 写在info.plist文件中的Scheme可能会被一些反编译手段获取到。
  2. URL Scheme可能会被劫持调来安全隐患,好比支付宝的URL Scheme劫持漏洞。
    固然这是避免的,如下引自乌云:

苹果能够限制 iOS 应用不能注册别的应用的 Bundle ID 做为 URL Scheme。这样的话,使用本身的 Bundle ID 做为 URL Scheme 的接收器就会变的安全不少。微信

第三方应用能够经过①给本身发送 URL Scheme 请求来证实没有被劫持,若是没有收到本身的 URL Scheme,就能够及时给用户发送提醒;②利用 MobileCoreServices 服务中的 applicationsAvailableForHandlingURLScheme() 来查看全部注册了该 URL Schemes 的应用和处理顺序,从而检测本身、或者别人的 URL Scheme 是否被劫持。app

注册自定义URL Scheme

注册自定义URL Scheme有两种方式组件化

  1. 在工程中的info.plist文件中添加对应的key值


    url

  2. tagets -> info -> URL Types 中添加

    代理

这两种注册方式本质上实际上是同样的只是位置不一样。code

URL Scheme相关验证

从其余应用或Safari中使用URL Scheme拉起APP

咱们须要在APPdelegate中实现相应的代理方法:

iOS 9.0如下
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
iOS 9.0以上
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;

下面咱们经过Safari来验证:


- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    NSLog(@"%s",__func__);
    NSLog(@"options: %@", options);
    NSLog(@"URL scheme:%@", [url scheme]);
    NSLog(@"URL query: %@", [url query]);
    
    // 提示并展现query
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"打开URL Scheme成功"
                                                        message:[url query]
                                                       delegate:nil
                                              cancelButtonTitle:@"肯定"
                                              otherButtonTitles:nil];
    [alertView show];
    
    return YES;
}

在当前应用中使用URL Scheme

在应用中调用URL Scheme须要是如下方法:

iOS10.0如下使用该方法:
- (BOOL)openURL:(NSURL*)url NS_DEPRECATED_IOS(2_0, 10_0, "Please use openURL:options:completionHandler: instead") NS_EXTENSION_UNAVAILABLE_IOS("");
iOS10.0以上使用该方法:
- (void)openURL:(NSURL*)url options:(NSDictionary<UIApplicationOpenExternalURLOptionsKey, id> *)options completionHandler:(void (^ __nullable)(BOOL success))completion NS_AVAILABLE_IOS(10_0) NS_EXTENSION_UNAVAILABLE_IOS("");
还有一个方法能够判断对应URL Scheme是否存在通常和上述方法一块儿使用:
- (BOOL)canOpenURL:(NSURL *)url NS_AVAILABLE_IOS(3_0);

下面来验证一下:

- (void)btnClick:(UIButton *)sender {
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"schemeDemo://"] options:@{} completionHandler:^(BOOL success) {
        NSLog(@"完成");
    }];
}

相关文章
相关标签/搜索