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<UIApplicationOpenURLOptionsKey, id> *)options{
    return [SchemesManager handleOpenURL:url];
}


@end

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

#import "SchemesManager.h"
#import <UIKit/UIKit.h>

@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<NSURLQueryItem *> *queryItems = [comp queryItems];
        for (int i=0; i<queryItems.count; i++) {
            NSURLQueryItem *item = queryItems[i];
            [str appendFormat:@"%@=%@ ", item.name, item.value];
            if(i<queryItems.count-1) {
                [str appendString:@","];
            }
        }
    }
    
    UIAlertView *alertView=[[UIAlertView alloc] initWithTitle:@"分享" message:str delegate:self cancelButtonTitle:nil otherButtonTitles:@"分享完成", nil];
    [alertView show];
    return  YES;
}


+ (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    //返回URL scheme = bank234280的主应用
    NSURL * url = [NSURL URLWithString:@"bank234280://success"];
    [[UIApplication sharedApplication] openURL:url options:nil completionHandler:^(BOOL success) {
    }];
}
@end

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

@implementation SceneDelegate

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

参考文章

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,295评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,928评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,682评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,209评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,237评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,965评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,586评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,487评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,016评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,136评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,271评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,948评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,619评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,139评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,252评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,598评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,267评论 2 358

推荐阅读更多精彩内容