端内外融合拉新,用户增长 -- 相关技术方案选型分析

上一篇聊 H5主流浏览器下App导流方案选取 的时候,有的朋友说这么多个方案只提了一个名字,没具体提原理和实现,这两天换工作,需要分享以前的用户增长心得,于是又重新梳理了一下

概述

1 需求背景

  • H5 网页端有着便于传播,方便在各类 APP与浏览器容器中进行推广,在扩充渠道上
  • APP 客户端用来承接,有着更好的体验与长久用户存留的收益与价值

如果能将用户从 H5 -> APP 的流程进行打磨,将体验进行优化,就能极大程度的提高拉新的转化率,而这其中的关键就是打破 H5 -> APP 之间传递数据,进行无缝衔接的方式。

2 目标

  • 在 H5 中,判断用户是否已经安装 App
  • 已经安装 APP 的用户,通过 Schema / Universal Link 的方式进行唤起与传递数据
  • 未安装 APP 的用户,通过 设备指纹 / 动态APK / 剪切板 / 苹果autoFill

需求背景,端内外融合可以让用户拉新的过程更加流程,降低门槛,提高转化。

img

3 方案需要解决的问题

  • H5 无法判断是否已经安装App
    • 需要先同时 schema 跳转
      • iOS上未安装App会弹出跳转失败弹框,不影响流程
      • UniversalLink 可以解决这个丑陋弹框的问题
    • 用下载页兜底
  • 在没安装App的情况下,把H5数据传递过去许
    • 几种方案都有覆盖面以及成功率的问题,各存在优缺点
    • 缺乏完美方案

4 市场上的一些解决方案

他们其实也都是用的上面提到的技术,只是统一封装好了服务,统一做好了解决方案。详细技术实现见下文

系统设计分析

1 H5中判断安装App

因为H5没有Api能够判断是否已经安装了哪些APP,目前广泛普遍采用的安卓iOS都支持的方案是

  • 尝试性唤起 Schema
  • 用下载落地页作为兜底,如果 Schema 失败,则自然转入下载

解决方案:

这里面暂时没有更好的解决方案,因为JS的能力十分有限,必须依赖宿主环境的能力,如果宿主环境是三方APP,倒是可以通过 JS Bridge 来通过 APP 进行一些是否安装 APP 的嗅探(canOpenUrl 之类的)

2 H5 在已安装 App 的情况下,跳转传值

2.1 安卓系统

  • 问题1:Schema 容易被浏览器/设备厂商禁止,目前很浏览器都禁止了 Schema
  • 优势:安卓 Schema 尝试跳转如果失败,不会有一个错误弹框

解决方案:

暂时想不到,除非和厂商或者渠道App合作开放 Schema 白名单。想要在不对外合作的条件下做更好的体验,一般是选择识别禁止 Schema 的浏览器UA,然后给页面进行蒙层提示用户用系统浏览器打开

2.2 iOS系统

  • 问题1:Schema 容易被浏览器/设备厂商禁止,目前很多 App or 浏览器 都禁止了 Schema

img

  • 问题2:Schema 存在被人抢注

  • 优势:iOS的浏览器内核相对统一,支持剪切板,是一个可以考虑的方案

  • 优势:iOS有 UniversalLink 会解决一些 Schema 的问题,但已然可以被三方浏览器禁止

解决方案:

1 使用 UniversalLink 来代替 Schema ,解决丑陋的弹框与Schema被抢注的问题

2 想要突破第三方浏览器禁止,除了对外合作白名单/蒙层提示系统浏览器打开。还可以考虑用剪切板,因为第三方浏览器一般都不会禁止跳转AppStore的链接

  • 识别禁止Schema的第三方浏览器UA
    • 点击下载,写入数据进入剪切板,同时跳转AppStore
    • AppStore上已经安装 App 会看到 “打开”按钮
    • 打开App,识别剪切板,读取数据
  • 这样的流程与蒙层提示系统浏览器打开相比,操作路径短一些,但是否用户体验更优见仁见智

3 H5 在未安装 App 的情况下,安装传值

目前一共有五种方案,可以在未安装App的情况下,给App传值

  • 设备指纹(通用)
  • 动态Apk(安卓)
  • 剪切板(iOS,安卓理论可行几乎不可用)
  • SFSafariViewController(iOS,很不稳定)
  • autoFill(iOS)

3.1 设备指纹方案

  • 方案流程

img

核心就是利用 H5 与 客户端读取到的设备唯一标识-设备指纹,当作key,利用服务器做数据中转传递数据,但想要找出合适的设备指纹需要解决几个问题

这个唯一标识要具备苛刻的条件,想找到其实很不容易

  • 选择当做唯一标识的内容,必须能让APP获取的到(UDID,MAC地址啥的,iOS都拿不到)
  • 选择当做唯一标识的内容,必须也能让H5获取的到(IDFA,IDFV等,JS拿不到)
  • 选择当做唯一标识的内容,还必须有能力区分出不同的设备(避免多个设备取出来的值一样,无法区分)

所以只能退而求其次,选取模糊设备指纹

  • 设备屏幕尺寸
    • 说明:iOS设备屏幕种类比较少,iOS下比安卓更容易冲突
  • 设备操作系统
  • 设备IP
    • 说明:IP会变,因此需要设计失效时间,最好 5min-10min以内有效
    • 说明:同公司WIFI下统一公网出口IP一致,很容易冲撞
  • MAC地址
    • 说明:Wifi下有类似 WebRTC JS通过路由器链路反向获取出MAC地址(还未实践)
    • 说明:Wifi下客户端也有一些技术方案可以通过路由器链路反向获取MAC地址(还未实践)
  • …… 等等

弊端:

成功率问题:因为最终选择的是模糊设备指纹,模糊匹配就存在成功率的问题,虽然选取更多的指纹参数可以提升,但无法做到100%。

  • iOS 成功率65% 左右
  • Android 成功率高一些

3.2 动态Apk方案(仅限安卓)

安卓的APK都是一个个ZIP包,因此可以在服务端在用户请求下载的时候,将用户的信息与数据写进母APK包的ZIP的注释信息里,为每个用户生成一个专属的APK,这个注释信息的写入不会影响包签名,可以在APP启动的时候由客户端代码读出。

  • 方案流程

img

  • 存在问题1:无法在通过渠道厂商使用

APK包是用户级别的定制包(某种意义上的千人千面包)不可能提供1个包给渠道市场,走渠道市场下载,只能走自己的 H5 下载页面直接进行安装

  • 存在问题2:比较占用带宽

APK包是用户级别的定制包(某种意义上的千人千面包),因此无法CDN,每次都是用户实时通过服务器动态进行打包,APK包又比较大,会有一些占用带宽,但完全能满足日常下载需求。如果遇到突发秒杀抢下载等活动需要注意小心

  • 存在问题3:安卓系统可能存在拦截

很多安卓系统,在下载非自己APP市场安装包的时候,会提示用户,当前APK包不是来自官方APP市场,建议用户去市场渠道下载的提示

  • 存在问题4:市场渠道抓包

很多市场渠道为了保证自己的APP版本最新,喜欢自己用脚本来官网抓包,来官网抓到的包是待动态APK信息的包,会影响原本市场渠道的优惠投放

3.3 剪切板方案

在 iOS 10 推出后,苹果遵循了 W3C 的剪贴板标准,在 Safari UIWebView WKWebView 都提供了 JS API 的剪切板能力,因此 iOS 10 之后,可以完全不借助 APP,直接通过 H5 发起剪切板

安卓上,剪切板的JSAPI,几乎在现在主流的各大系统与浏览器厂商,都不支持。但 Can I Use 上可以查到,高版本 Chrome 内核应该支持。安卓可以不用考虑这个方案了。

剪切板API依赖于DOM的点击,无法做到JS直接静默写入,所以流程上必须先请求好剪切板的值,然后写入H5 DOM,等待DOM被点击,写入剪切板。

  • 方案流程

img

  • 存在的问题

    • 剪切板都是系统共用,可以被任意APP修改覆盖,也可能被用户主动修改覆盖
    • 注意与其他剪切板口令冲突的情况(比如吱口令),仅识别自己的口令,使用完清除
    • JS 代码都是完全暴露的,在JS代码中做加密不可行,得需要服务端做加密,或者直接服务器存储,只返回密文或者服务器存储的Token凭证
    • 端代码在本地数据还原,可以使用自己的本地密文解密方案,也可以通过服务器存储的Token凭证,从服务器读取数据

3.4 SFSafariViewController方案(不推荐)

由于苹果的沙盒机制,业务APP与H5所在的浏览器APP分属于不同沙盒,Cookie是不互通的,因此在APP内起WebView,几遍访问同域名下网页,也无法获取Cookie中的数据。

在 iOS 9 刚推出 SFSafariViewController 可以在APP内打开属于系统Safari沙盒的一个网页,从而能与系统Safari共享数据。

方案流程:

  • 支持 iOS 9 以上
  • Safari 打开H5,网cookie中写入数据
  • APP安装,打开一个隐藏的SFSafariViewController
  • SFSafariViewController 访问一个H5 页面,用JS读取cookie数据,然后用Schema,传给已打开的App

存在问题:

  • H5 仅限Safari,三方浏览器,APP都无法支持
  • 隐藏SFSafariViewController,已经被苹果审核禁止,如果想要使用这个方案,得显性的在APP内打开SafariVC界面才能传递数据

3.5 autoFill方案(调研中)

苹果在 iOS 11 中提供了 autoFill 能力,能够实现在 Safari 网页中,自动记录下来的用户名与密码,在 App 中无缝的自动填充

方案流程:

  • 在H5中对表单控件开发密码自动记录keychain的功能
    • 不要使用 H5 Cookie 式记住密码
    • 使用 input 的 type = ‘password’ type = ‘name’ 的浏览器记住密码方式
  • 配置 apple-app-association
    • 域名根目录下配置 apple-app-association 的 json file
    • app 开启 Assocated Domains,并配置域名
  • UITextView/UITextFiled 配置
    • 设置 TextContentType 属性为 username 与 password
  • 当用户点击输入密码,会提示自动输入

img

  • 存在问题:
    • 数据传递场景只适用于登陆名密码,不适合传递其他数据
    • 以自动记住密码的形式会给用户带来不安全感
    • 可以被用户设置上关闭
    • 所有记住密码与自动提示都会有系统级显性的UI感知,无法做到静默传递

推荐解决方案

由于每一种方案都无法做到完美,所以采用多种方案按着优先级组合生效

1 安卓推荐方案

  • 通过Schema跳转,兜底下载落地页,判断是否安装
  • 已安装App
    • Schema 打开,直接传递数据
    • 对于封禁Schema跳转的浏览器UA,采取蒙层提示系统浏览器打开
  • 未安装App
    • 自主H5网页渠道,采用动态APK
    • 外部市场渠道,采用设备指纹匹配(失败率略高,做好未匹配兜底方案)

2 iOS推荐方案

说明:UniversalLink 属于iOS平台专属,他与schema能力差异不大,为了统一安卓与iOS的实现,完全可以用Schema替换

  • 通过UniversalLink跳转, 兜底下载落地页,判断是否安装
  • 已安装App
    • Universal Link 打开,直接传递数据
    • 对于封禁 UniversalLink 的浏览器UA,采取蒙层提示系统浏览器打开
    • 对于封禁 UniversalLink 的浏览器UA,也可以采取剪切板+跳转Appstore打开的方式
  • 未安装App
    • 剪切板方案,适用任何场景
    • iOS10以下,采用设备指纹匹配兜底(失败率略高,做好未匹配兜底方案)