0x00 引言
为了推广产品,产品通常会设计一个二维码,扫描这个二维码进入一个H5页面,H5页面中提供一个链接按钮,点击这个按钮或者直接调起应用或者跳转至AppStore引导下载。
在国内,微信基本上已经变成了事实上的扫码工具(不得不说,微信的扫码模块算法优化的非常强悍,速度和识别率绝对是首屈一指),所有我们设计的H5页面绝大多数情况下是在微信中展示。因此我们研究的重点也会侧重于从微信中调起应用的方法。
下面会介绍几种从H5中调起iOS应用的几种方法。
0x01 URL Scheme
由于苹果的app都是在沙盒中,相互是不能访问数据的。但是苹果还是给出了一个可以在app之间跳转的方法:URL Scheme。简单的说,URL Scheme就是一个可以让app相互之间可以跳转的协议。
我们所使用的每一个app就相当于一个功能,app的跳转可以使得每个app就像一个功能组件一样,帮助我们完成需要做的事情,比如三方支付,搜索,导航,分享等等。
官方的参考文档:About Apple URL Scheme
在iOS系统中,通过URL Scheme的方式启动应用和参数的传递的步骤如下。
1 创建URL Scheme
首先在Info.plist中添加一行,选择URL types;
在展开的Item 0中填写URL identifier,这个用来唯一标识用户自定义的URL Scheme,推荐使用域名的反转形式,如:com.tsingwill.mylink;
在Item 0中添加新的一行,选择URL Schemes, 展开URL Schemes,在Item 0中输入自定义的Scheme的名称。在这里只需要输入自定义的Scheme的名称即可,不需要加上://,例如这里输入的是mylink,那么对应的自定义的URL就是mylink://,这里可以输入多个。
完整的示例图如下:
2 使用URL Scheme
(1)在Safari中直接在浏览器的地址栏中输入mylink://,即可启动刚才的应用;
(2)在其他的应用程序中使用,在需要调用的地方使用下面的代码即可实现调用。
NSString *customURL = @"mylink://";
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:customURL]];
如果需要传递参数,可以通过?传递,例如:
- (void)openOtherApp
{
NSString *customURL = @"mylink://?token=123abct®istered=1";
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:customURL]];
}
(3)在AppDelegate中可以实现下面的代理方法
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
if ([sourceApplication isEqualToString:@"com.devzeng.demo.urlscheme"]) {
NSLog(@"调用的应用程序的Bundle ID是: %@", sourceApplication);
NSLog(@"URL scheme:%@", [url scheme]);
NSLog(@"URL query: %@", [url query]);
return YES;
} else {
return NO;
}
}
3 URL Scheme的限制
设计好H5页面并且配置了URL Scheme后,迫不及待地拿出微信扫下试试,结果发现并没有效果。原来微信对第三方应用的URL Scheme进行了屏蔽,只有加入白名单(交钱)后的URL Scheme才会被放行(可能微信的初衷是防止有人借助于微信平台恶意推广营销)。
如果不想合(交)作(钱),我们只能在H5页面中放上一个条件蒙版:如果是在微信中打开的H5,就展示蒙版,提示用户点击右上角“通过Safari打开”。
0x02 Universal Link
1 What is Universal Links?
通用链接:一种能够方便的通过传统HTTP链接来启动APP, 使用相同的网址打开网站和APP,旨在打造无缝链接APP的体验。首次出现在2015 WWDC上, 是Apple为iOS 9宣布的一个所谓通用链接的深层链接特性。
官方文档:Support Universal Links
2 配置支持Universal Link
(1)Universal Link最低支持iOS9。
(2)添加域名到 Capabilities。
Associated Domains设置为Enable
设置Capabilities -> Associated Domains ,例如:
applinks:domain.tsingwill.com
(3)创建apple-app-site-association文件
apple-app-site-association是一个纯文本json文件(注意不包含josn后缀名), 放置于服务器的/.well-known目录(开发者需要自己想办法搞一个https服务器)。例如:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "F7*******.com.tsingwill.mylink",
"paths":[ "/mylink/*" ]
}
]
}
}
(4)前端调起方式
前端(H5)可以通过标准的HTTPS的方式进行调起,例如:
https://domian.tsingwill.com/mylink/scan
如果想要传递参数,同样可以通过?的方式进行传递。
(5)APPDelegate中响应回调
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
if (![userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
return YES;
}
NSURL *webUrl = userActivity.webpageURL;
// do what else about NSURL
}
(6)Universal Link的问题梳理
Universal Link是从iOS9开始支持的。但在iOS9.2中,苹果调整了一些规则(估计也是防止恶意推广链接),从iOS 9.2开始,在相同的domain内Universal Links是不work的,必须要跨域才生效,我们实测值需要跨子域名即可,比如 m.domain.com 跳转 o.domain.com 是可以触发跳转App。从iOS 9.2开始,直接把 Universal Link 拷贝到 Safari 的地址栏是无效的,在相同的 domain 内 Universal Links 是无效的,通过 js 调用也是无效的,真的是醉了。
(7)Universal Link的完整流程
0x03 URL Scheme + Universal Link
现阶段还是要提供对iOS8的支持,开发时可以对URL Scheme和Universal Link都提供支持,前端调用时判断系统的版本,如为iOS9以下则采用URL Scheme的方式调用,若为iOS9+则采用Universal Link的方式调用。
0x04 关于WXAppExtendObject
微信提供了SDK,成为付费开发者后,可以通过WXAppExtendObject中提供的API让自己的应用成为白名单应用。
0x05 使用第三方提供的方案
魔窗,企业级深度链接(Deeplink)解决方案,让App能像Web一样通过URL进行任意内容的分发、管理和一链直达 ,一键唤醒App内指定页。实质上也是对Universal Link等方式的包装,并提供WEB服务器,开发者无需再自己搭服务器。具体使用可参考魔窗