需求描述

此类需求多出现在运营活动中,通过社交分享的 H5 页面中会有用户交互按钮。用户点击按钮后,如果本机安装了 APP,那么需要打开/跳转至该 APP 中,并在 APP 中触发对应的操作,否则进入到 APP 下载页,引导用户下载 APP,从而获取到新用户增量。

demo

以前的实现方式

在 iOS8 和 Android x.x 之前,前端大神们找到了一个很溜的方法来实现 通过 URL Schemes 跳转 APP 后触发回调函数

浏览器接收到 URL 请求发现未知协议,会交给系统处理,系统就能调起客户端了。我们还能趁机检查一下用户是否安装客户端:给iframe 设置一个3-5秒的 CSS3 的transition过渡动画,然后监听动画完成事件,如果用户安装了客户端,那么系统会调起,并将浏览器转入后台运行,进入后台的浏览器一般不会再执行 CSS 动画,这样,我们就能通过判断 CSS 动画执行的时长是否超过预设来判断用户是否安装某个客户端了。

不过这种通过新建一个 iframe 触发 URL Schemes 的方法已经在新版 iOS 和 Android 系统中失效,只是回看下大神们奇异的脑回路。

现在的实现思路

大家在拿到这个需求的时候,肯定觉得很简单,直接在2个按钮中加上 URL Schemes 不就完事了吗 URL://action?query=x ?其实我们还遗漏了产品的另一个需求:如果用户没有安装 APP 需要跳转到下载页面,指引用户进行下载。

但是因为我们已经无法通过 URL Schemes 判断用户是否已经安装了,自然我们也不知道何时需要将用户带到我们的下载页中。

1. 引入中转宣传页

我们不妨改变一下思路,为什么要先触发 URL Schemes 再跳转,而不是先去一个用户可以下载 APP 的页面,再在这个页面触发一次 URL Schemes ,顺带还可以在这个页面做一波品牌宣传。说做就做,我们先来设计下这个作为中转的宣传页:

demo

这个宣传页主要由三部分组成:上部宣传海报、中部下载按钮、下部提示文案+再次触发指引。完美~

2. 通过 URL Schemes 唤起 APP

中转宣传页除了达到宣传的作用外,还作为一个全局的跳转处理页面存在,其他活动页不需要额外的处理跳转逻辑,只需要把操作类型和参数组装成一个标准 URL 供用户点击即可。

不要小看这个页面的逻辑,并非简单的触发一个 URL Schemes ,还要处理微信内置 webview 被阻止的用户提示以及后面的 Universal Links 。所以由一个页面统一的去处理这些逻辑,显然是非常必要的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 通过 URL 中的 query 参数,组装一个 Url Scheme 出来
function getUrlScheme() {
var scheme = 'app://'
var query = parseUrlQuery()
if (query.hasOwnProperty('action')) {
scheme += query['action']
scheme += location.search
return scheme
} else {
return null
}
}
window.onload = function() {
var scheme = getUrlScheme()
// 发起一个 Url Scheme 尝试跳转 APP
scheme && window.open(scheme, '_parent');
}

理想很丰满,现实很骨感,提测的包又被打回了。URL Schemes 的方式主要有下面几个缺点:

  • iOS 跳转 APP 之前有一个弹窗,需要用户二次确认
  • iOS 未安装 APP 的用户会得到一个:无法识别的链接的 alert 提示框
  • 在第三方 APP (比如微信)这种协议被阻断掉了,完全没反应

查查资料,iOS9 之后有一个叫 Universal Links 的东西,它的主要原理是:APP 设置好白名单域名,用户在安装好这个 APP 后,系统会根据这个域名从根目录下面的 apple-app-site-association 配置文件中获取到相关的配置信息保存在系统中。系统监听页面访问请求,如果用户从 A 页面点击链接尝试跳转到 B 页面,而 B 页面 URL 属于 Universal Links,那么这个请求将会被系统阻止并跳转到对应的 APP 内。(B 页面将不会被打开,所以配置里面的 PATH 很重要,不然用户可能永远没有机会看到你的 B 页面,除非手工输入 URL 访问)

它的优点主要是:

  • 已安装 APP 的用户在从活动页点击按钮尝试跳转到宣传页的时候,会被系统拦截,直接跳转到 APP(就是点击“我要领取”,直接进入 APP,不会再去到宣传页了)
  • 直接访问宣传页,头部会有一个 APP 介绍 banner,可以手工触发跳转
  • 重点!重点!由于这个是系统的行为,在第三方 APP (比如微信)无法拦截这种协议的跳转

至于如何配置 Universal Links ,我这里就不再累赘,网上应该大把的资料,推荐一篇文章给大家吧:《iOS 9 通用链接(Universal Links)》

那我们就再完善下代码吧~

1
2
3
4
5
6
7
8
9
10
11
12
window.onload = function() {
var scheme = getUrlScheme()
if (scheme) {
// 如果是微信内部或者 iOS9 以上的话,就不发送 URL Shceme 请求了,直接通过 Universal Links 跳转 APP
if (ua.isWeChat() || (ua.isiOS() && ua.getiOSVersion()[0] > 8)) {
console.log('try to launch app with universal links')
} else {
console.log('launch app with url scheme')
window.open(scheme, '_parent');
}
}
}

好了,终于可以放心的推广活动了!O(∩_∩)O~~