H5唤起APP实践指南
应用场景
H5唤醒APP常见的应用场景是在一些活动页面引导用户进行下载或打开APP以达到推广引流的作用。一般有以下两种情况:
- 引导已下载APP用户打开APP,提升用户体验,用户粘性
- 引导未下载APP用户去下载APP,推广引流,增加用户量
方案介绍
1、URL Scheme
简介
相信大家都知道 URL,例如https://www.baidu.com就是一个URL。
在 😕/ 之前的部分就称为 URL Scheme。
也就是说https://www.baidu.com的 URL Scheme 就是 https。
简单来说,URL Scheme 就是一个可以让 app 相互之间可以跳转的协议。
就像给服务器资源分配一个 URL,以便我们去访问它一样,我们同样也可以给手机APP分配一个特殊格式的 URL,用来访问这个APP或者这个APP中的某个功能(来实现通信)。APP得有一个标识,好让我们可以定位到它,它就是 URL 的 Scheme 部分。
语法
URI = scheme:[//authority]path[?query][#fragment]
// 其中授权信息包含以下部分,具体查看[wiki](https://en.wikipedia.org/wiki/URL)
authority = [userinfo@]host[:port]
例子
- 微信:weixin://
- 支付宝:alipay://
- 淘宝:taobao://
- 其他自定义Scheme:yxstock://yx.stock.app/pathname?key1=value1&key2=value2
2、Intent
安卓原生Chrome浏览器在18之前的版本支持URL Scheme,25之后版本功能做了变化,不再支持通过设置iframe src属性来唤醒APP。例如,即使安装了APP,设置
<iframe src="paulsawesomeapp://page1"> </iframe>
也无法打开APP。需要实现谷歌官方提供的 intent: 语法,或者实现让用户通过自定义手势来打开APP。
语法
intent:
HOST/URI-path // Optional host
#Intent;
package=\[string\];
action=\[string\];
category=\[string\];
component=\[string\];
scheme=\[string\];
end;
具体的解析详情可以查看源码。
同样地,可以在end;字符串前面添加一个跳转失败后的地址:
S.browser_fallback_url=[encoded_full_url]
当APP无法唤起的时候,将会跳转到上面给到的地址。
例子
下面是打开 Zxing 二维码扫描 APP 的 intent例子:
intent:
//scan/
#Intent;
package=com.google.zxing.client.android;
scheme=zxing;
end;
可以通过以下方式来唤起APP:
<a href="intent://scan/#Intent;scheme=zxing;package=com.google.zxing.client.android;end"> Take a QR code </a>
3、Universal Link
Universal Link是什么
Universal Link 是苹果在 WWDC2015 上为 iOS9 引入的新功能,通过传统的 HTTP 链接即可打开 APP。如果用户未安装 APP,则会跳转到该链接所对应的页面。
为什么要使用 Universal Link
传统的 Scheme 链接有以下几个痛点:
- 在 ios 上会有确认弹窗提示用户是否打开,对于用户来说唤端,多出了一步操作。若用户未安装 APP ,也会有一个提示窗,告知我们 “打不开该网页,因为网址无效”
- 传统 Scheme 跳转无法得知唤端是否成功,Universal Link 唤端失败可以直接打开此链接对应的页面
- Scheme 在微信、微博、QQ浏览器、手百中都已经被禁止使用,使用 Universal Link 可以避开它们的屏蔽( 截止到 18年8月21日,微信和QQ浏览器已经禁止了 Universal Link,其他主流APP未发现有禁止 )
如何让 APP 支持 Universal Link
简单概述配置方法,具体详细配置可以查看官方文档。
- 拥有一个支持 https 的域名
- 在 开发者中心 ,Identifiers 下 AppIDs 找到自己的 App ID,编辑打开 Associated Domains 服务。打开工程配置中的 Associated Domains ,在其中的 Domains 中填入你想支持的域名,必须以
applinks:
为前缀 - 配置
apple-app-site-association
文件,文件名必须为apple-app-site-association
,不带任何后缀 - 上传该文件到你的 HTTPS 服务器的 根目录 或者
.well-known
目录下
唤起方式
通过前面的介绍,我们可以发现,无论是 URL Scheme 还是 Intent 或者 Universal Link ,他们都算是 URL ,只是 URL Scheme 和 Intent 算是特殊的 URL。所以我们可以拿使用 URL 的方法来使用它们。
1、iframe
<iframe src="weixin://qrcode">
优点:支持URL Scheme情况下,在未安装 app 的情况下,不会去跳转错误页面。
缺点:部分系统兼容性问题,不支持URL Scheme。例如,安卓系统原生浏览器25版本后则不支持iframe唤醒APP。
2、a标签
<a href="intent://scan/#Intent;scheme=zxing;package=com.google.zxing.client.android;end"> Take a QR code </a>
3、window.location
URL Scheme 在 ios 9+ 上诸如 safari、UC、QQ浏览器中, iframe 均无法成功唤起 APP,只能通过 window.location 才能成功唤端。
当然,如果我们的 app 支持 Universal Link,ios 9+ 就用不到 URL Scheme 了。而 Universal Link 在使用过程中,在 qq 中,无论是 iframe 导航 还是 a 标签打开 又或者 window.location 都无法成功唤端,一开始我以为是 qq 和微信一样禁止了 Universal Link 唤端的功能,其实不然,百般试验下,通过 top.location 唤端成功了。
唤起异常处理
如果在APP未安装情况下唤醒失败,则需要做下处理,可以是跳转下载页, 或者ios 跳转 App Store。Android Intent 和Universal Link 自身机制允许它们唤端失败后直接导航至相应的页面,但URL Scheme则无法做到,需要通过hack手段来判断唤醒状态来做处理:
const handleClickOpenApp = () => {
let isWakeApp = false
// if viewport is changed, that means app have been waked up.
document.addEventListener('visibilitychange', () => {
isWakeApp = true
})
// if app is installed then wake up.
go('usmart-global://stock.app')
// if app fails to wake up,then go to download page.
setTimeout(() => {
if (!isWakeApp) {
handleClickDownloadApp()
}
}, 2000)
}
const go = (url: string) => {
if (!url) return
window.location.href = url
}
APP 如果被唤起的话,页面就会进入后台运行,会触发页面的 visibilitychange 事件。如果触发了,则表明页面被成功唤起。没有唤醒则定时器2秒后跳转到相应的落地页作为兜底处理。
最佳实践
为了兼容不同终端,建议url Scheme、Intent、Universal Link 一起使用😄。