APP URL Schemes

前言

通常来说,手机APP相当于是一座座信息孤岛,APP之间不能相互通信;但有些场景的确需要,让别的APP来唤醒自己,例如支付宝为别的APP提供支付,又或者需要在一个营销网页中打开APP的指定页面, 这时就可以利用定义自己的URL Schemes页面跳转协议来实现。

一.什么是URL Schemes

1.URL Schemes单词理解

  • URL, 我们都很清楚,https://www.apple.com 就是一个URL,我们叫它链接或者网址。
  • Schemes, 表示的是一个 URL 中的一个位置——最初始的位置,即 ://之前的那段字符。比如 https://www.apple.com 这个网址的 Schemes 是 https。

2.简单理解

例如微信打开扫一扫的功能的Schemes是:weixin://dl/scan;我们可以理解,在以本地应用为主的 iOS 上,我们可以像定位一个网页一样,用一种特殊的 URL 来定位一个应用甚至应用里某个具体的功能。而定位这个应用的,就是这个应用URL 的 Schemes 部分。

3.APP和网页的对比

你可以完全按照理解一个网页的 URL (也就是它的网址)的方式来理解一个 iOS 应用的 URL,拿苹果的网站和 iOS 上的微信来做个简单对比:

网页(苹果) iOS 应用(微信)
网站首页/打开应用 https://www.apple.com weixin://
子页面/具体功能 https://www.apple.com/mac(Mac页面) weixin://dl/moments(朋友圈)

在这里,https://www.apple.comweixin:// 都声明了这是谁的地盘。然后在 https://www.apple.com 后面加上 /mac 就跳转到从属于 https://www.apple.com 的一个网页(Mac 页)上;同样,在 weixin:// 后面加上 dl/moments 就进入了微信的一个具体的功能——朋友圈。

二.iOS中如何使用URL Schemes

1.注册URL Schemes

为自己的项目Bank注册一个URL Schemes,支持被唤醒。


Register Your URL Scheme

Identifier是自定义的 URL schemes 的名字,一般采用反转域名的方法保证该名字的唯一性,比如 com.lwin.www,不过在iOS中打开一个应用程序只需要拿到这个应用程序的协议头URL Schemes即可,所以我们只需配置应用程序的协议头即可。一个应用是可以有多个URL Schemes的。

2.使用

a.唤醒应用

在另外一个APP唤起Bank

- (IBAction)open:(id)sender {
    if(![[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"LBSAPP://"]]) {
        return;
    }
    //不带参数
     NSString * wslUrlScheme = @"LBSAPP://product";
    //如果参数含有特殊字符或汉字,需要转码,否则这个URL不合法,就会唤起失败;参数字符串的格式可以自定义,只要便于自己到时候解析就行;
    NSString * parameterStr = [@"?name=手机&id=1" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    //LBSAPP://product?name=手机&id=1
    NSURL * url = [NSURL URLWithString:[wslUrlScheme stringByAppendingString:parameterStr]];
    //iOS 10以下
//    [[UIApplication sharedApplication] openURL:url];
    //iOS 10以上
    [[UIApplication sharedApplication] openURL:url options:nil completionHandler:^(BOOL success) {
    }];
}

如果点击调用时控制台报错:
-canOpenURL: failed for URL: "LBSAPP://" - error: "This app is not allowed to query for scheme lbsapp"
这是因为在iOS9以后,如果使用 canOpenURL:方法,该方法所涉及到的URL Schemes必须在"Info.plist"中将它们列为白名单,否则不能使用。

添加URL Schemes探测白名单

b.被唤醒之后的处理

  1. 在AppDelegate里面的UIApplicationDelegate代理方法做监听。
#import "AppDelegate.h"
#import "ViewController.h"
#import "SchemesManager.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];
    
    self.window.rootViewController = [[ViewController alloc] init];;
    
    [self.window makeKeyAndVisible];
    //第三方应用打开本应用启动
    if(launchOptions[UIApplicationLaunchOptionsURLKey] != nil){
        [self application:application handleOpenURL:launchOptions[UIApplicationLaunchOptionsURLKey]];
    }
    // Override point for customization after application launch.
    return YES;
}
/**
 iOS 9.0 以下  程序运行过程中调用
 */
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
    return [SchemesManager handleOpenURL:url];
}

/**
 iOS 9.0 以下   程序运行过程中调用
 */
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation{
    return [SchemesManager handleOpenURL:url];
}

/**
 iOS 9.0 之后
 三方唤起本程序后执行的方法
 return YES 表示允许唤起本程序  程序运行过程中调用
 */
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options{
    return [SchemesManager handleOpenURL:url];
}


@end

2.可以单独写一个工具类来处理URL Schemes。

#import "SchemesManager.h"
#import 

@implementation SchemesManager

+ (BOOL)handleOpenURL:(NSURL *)url {
    
    NSMutableString *str = [NSMutableString string];
    [str appendFormat:@"URL scheme:%@ \n\n", [url scheme]];
    [str appendFormat:@"URL host:%@ \n\n", [url host]];
    [str appendFormat:@"URL absoluteString:%@ \n\n", [url absoluteString]];
    
    NSURLComponents *comp = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
    if(comp) {
        [str appendString:@"queryItems:\n"];
        NSArray *queryItems = [comp queryItems];
        for (int i=0; i

3.注意
如果使用了Scene,需要在SceneDelegate的代理方法
- (void)scene:(UIScene *)scene openURLContexts:(NSSet *)URLContexts去处理URL Schemes :

@implementation SceneDelegate

- (void)scene:(UIScene *)scene openURLContexts:(NSSet *)URLContexts {
    UIOpenURLContext *urlCtx = [URLContexts allObjects].firstObject;
    [SchemesManager handleOpenURL:urlCtx.URL];
}
@end

参考文章

URL Schemes 使用详解
iOS scheme跳转机制

你可能感兴趣的:(APP URL Schemes)