分享闭环的意义
看了最近热播电视剧《创业时代》, 感受了一波创业的波折, 守业的艰辛. 对于初创产品需求主要是: 1)品牌感知, 2)引导下载 App 体验, 追求更多的是下载量. 对于已经基本成型的产品来讲需要, 关注更多的是, 手机生态中所提供服务使用的连贯性, 追求更多的则是 DAU/MAU.
从最近 AppStore 中 App 更新频率来看, 明显可以感受到现在市场对 App 的重视程度. 然而当下 App 之间竞争激烈, 好不容易吸引过来的用户不想轻易被别的 App 抢走, 但又想夹缝中求生存费劲形式想从别人家的 App 中导流来自己 App, 在这样的矛盾和糟糕环境中, 分享和分享回流一直倍受老板和业界关注.
分享逻辑闭环可以拆解来看一下, 如图:
APP_A 一般指的是非社交平台 App,APP_B 一般是带有社交属性的 App, 可以简单理解为: XXAPP 跟微信的关系. 现阶段微信一家独大, 微信做了连接一切的事情, 被公认为是传播最有效的渠道. 各家也是想法设法充分利用好这个平台.
上图中两个虚线框, 按照需求关系『分享功能』是有较稳定的解决方案 (NA 有分享 SDK 或配置, H5 可以借助 NA 进行功能实现), 不在本文讨论范围.『回流功能』则是需要集成大前端(FE\Android\iOS) 所有力量进行攻破的课题.
Native 现状梳理
调起 App 方案梳理
场景 | 调起原理 | 外部调用方式 | 下载 | 参数携带 |
---|---|---|---|---|
Android 浏览器 | <data android:scheme="myscheme://" /> | 1. location.href="myscheme://xxx" 2. | 1. location.href="myhost://xxx.apk" 2. location.href="应用市场(下表)" | URL 拦截 |
IOS 浏览器 | Universal Links (IOS9+) 1. 创建 apple-app-site-association 2. Xcode 的 capabilities 配置域名信息 < br ztid="135" ow="0" oh="0"> 3. AppDelegate.m 中支持 | 1. 访问配置的域名 (http://a.com ) 跳转 http://a.com ) | location.href="https://itunes.apple.com/tw/app/id123123 " | URL 解析:userActivity.activityType.webpageURL |
IOS 浏览器 | Scheme:- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url | location.href="myscheme://xxx" | 同上 | URL 拦截 |
微信 | 白名单机制 < br ztid="154" ow="0" oh="0">1. 白名单内的支持调起 < br ztid="155" ow="0" oh="0"> 2. 其他如果在应用宝发布,可以通过应用宝间接调起 | location.href="http://a.app.qq.com/o/simple.jsp " | 携带给应用宝,交给他们处理 | location.href="http://a.app.qq.com/o/simple.jsp " |
Android 各大应用市场 Scheme
平台 | sheme | 正则 |
---|---|---|
小米 | mimarket://details?id=xxx&back=true | /\(.Android. (MI|Mi" Redmi|HM NOTE| 201\d{4} Build).*)|Android.*XiaoMi/ |
sumsung | samsungapps://ProductDetail/xxxx | /\(.Android. (SAMSUNG|SM-|GT-).*)/ |
华为 | appmarket://details?id=xxxx | /\(.Android. (HUAWEI|HONOR|HW- |
oppo | oppomarket://details?packagename=xxxx | /Android.*(OPPO|A31.? Build|R\d+(Plus)? Build)|Android.*OppoBrowser|^OPPO/ |
vivo | vivomarket://details?id=xxxx | /\(.Android. (vivo|VIVO).*)/ |
调起流程设计
说明: 设计方案是按照两个域名的方案设计. http://A.COM 和 Universal Link(Ulink) 分别是两个不同域名
调起实战
机缘本次项目调起功能的实现, 从源头深入了解并实现了调起功能, 实战过程中的几个点总结起来跟大家一起分享.
微信拦截调起咋回事
2018 年初, 微信干了一件蛋疼的事情, Universal link 进行白名单机制. 之前限制了 scheme 开发者不得不转向 Ulink 方案, 但是这样一来完全把微信内调起封死. 如果想调起, 需要进入其白名单, 具体方法不得而知.
白名单 Android 同学反编译分析出来的, 具体怎么做的如有微信同学, 欢迎出来批评指正, 愿听其详.
微信限制后有三个方案:
右上角三个点, 浏览器打开;
跳转应用宝, 连接 scheme;
iOS 直接跳转 Appstore 打开, 但无法携带参数.
域名需要几个
域名是一个可选项.
无域名方案
也就是所谓的 scheme 方案, 安卓 & iOS 都可以通过 scheme 方案来实现.
想到一个问题: 如果定义自己 App 的 schema 为一个别人 App 的 sheme(如 wx://)它会调起谁? 实战发现, 会调起后安装的 App. 如此使用 scheme, 想必会产生一系列问题. 也许这是 iOS 使用 ulink 的考虑出发点.
为了不必要的冲突 scheme 命名还是要多考虑一层的.
单域名方案( http://A.com )
直接打开页面无法跳转对应的 Ulink(因为 iOS 9.2 之后规定, Ulink 必须跨域访问才能生效). 但实践证明当单域的时候, 分享到微信, 再次选择用浏览器打开, 如果已经安装 App, 会自动调起. 这是比较完美的用户体验.
从别的页面跳转到当前单域名下, 理论上因为 IOS9 + 的 Universal Link 使得调起的用户体验更加流畅, 所以理论上有一个域名, iOS 配置没问题就可以调起. 实战过程中遇到两个蛋疼的问题:
有些用户会长按复制 URL 在浏览器直接打开无法调起, 无法调起;
如果恰好安装了 App, 合作方页面 ( http://B.com ) 跳转到页面 ( http://A.com ) 不会看到页面直接调起, 合作方一般对这种行为非常反感, 因为直接跳离了他们 App.
多域名方案( http://A1.com & http://A2.com )
为了解决单域名的两个痛点, 降级体验. A2.com 作为 Ulink 的配置, 先进入 A1.com 的页面, 多一步点击操作, 然后跳转 A2.com 页面进行后面逻辑操作.
调起是怎么请求的
iframe or location
H5 调起 NA 的第一种模式是 scheme.
不论 iframe 还是 location, 其实本质都是要发出一个 scheme 请求, App 可以监听到提前约定好的协议, 进而启动 App. 如果没安装 App, 也期望不会对用户体验造成伤害.
iframe 的特点是页面不会跳转, 当前访问页面无感知(具体实现如下), 不过遗憾的是 IOS9 之后就不支持了.
- let last;
- let invoke = function(scheme) {
- last = +Date.now();
- let $node = document.createElement('iframe');
- $node.style.display = 'none';
- $node.src = scheme ;
- let body = document.body || document.getElementsByTagName('body')[0];
- body.appendChild($node);
- setTimeout(function() {
- body.removeChild($node);
- $node = null;
- }, 10);
- };
- invoke(scheme);
- setTimeout(function() {
- // 防爆点
- if (Date.now() - last < 1600) {
- location.href = unifiedDownloadURL;
- }
- }, 1500);
location 的特点是 history 可能会发生变化, 同时些特殊 App 的 webview 发现未知协议还会跳转到一个错误页面, 不过 iOS 如果 scheme 的话只能这么搞了.
所以我的结论: Android iframe & iOS src
前端跳转 or 服务端跳转
H5 调起 NA 的另一种模式是 Universal Link.
在启动服务端方案之前, 设计了一版纯前端的方案. A2.com 配置 Ulink ,A1.com-A2.com 的过程中如图, 1)需要一个中间页承载, 2)需要手动出发跳转下载或者定时促发, 这不是用户期望看到的.
为了减少用户感知, 将 A2.com 对应的中间页跟下载页 URL 打包, 访问 A1.com 后, 点击跳转 A2 服务端提供接口, 直接 302 跳转对应下载 ULR(当然也可以 Nginx 配置转发, 但为了可维护性, 建议写到业务中)
中间页的意义
通过上述服务端跳转来讲, 也许中间页是没有存在意义的. 要么调起, 要么跳转下载, 完全不需一个中间页. 仔细想一下还是有两个弊端的:
调用复杂. 抽离调起方法, 但如果但业务多地方, or 多业务多产品线引用的时候, 就显得有点冗余. 这时候如果有一个中间页, 调用方只需要跳转过来即可
缺少品牌宣传. 如业务初期, 无外部落地页, 比如一个海报加一个二维码想调起, 这个时候如果没安装 App 的时候, 也没有品牌宣传直接引导到 APPstore 或者直接下载, 略显强硬. 这就要根据业务具体情况来看中间页存在的意义.
调起的极致化体验
二次分享
在微信中有如图的几种分享状态, 第一个是 App 分享后的, 后面两个是对分享的再次分享的不同状态. 这需要进行一些微信的配置, 才能达到 2 图的效果. 后面有机会可详细分享.
监听来源, 引导回流
最近发现一些 App, 从 A 应用跳转到 B 应用, B 应用里会提示返回 A 应用的提示. 跳转原理是一致的都是监听别人调起然后, 调起别人, 理论上都是 scheme 的具体应用.
判断 App 是否安装
有些应用为了考虑更多的兼容性, 选用上面提到的中间页方案. 这个时候是立即打开? 还是立即下载? 如果知道应用在手机里安装的状态, 对于用户体验来讲应该是较为重大的提升. 可惜系统没有提供这样的接口, H5 跟 NA 都无法准确获取. 不过可以开动脑筋, 利用服务端, 通过对 App 打开情况对设备号, 登录状态, 设备标识, IP 等信息记录, 打开下载页的时候, 准确提示用户是下载还是打开. 后面有机会的话常识去做一下.
总结
本人最近参与做了一个创新型 App, 关于调起这块进行了全方位的了解.
关于技术选择: 初期选择: iOS 单域名, Android Scheme 调起, 服务端 302 分发下载连接, 在分享出来的落地页上突出品牌宣传, 完成调起功能. 后期产品做大了, 引入中间页通用方案, 提供更加通用解决方案.
关于用户体验: 这个社会为了利益, 无奈让开发者夹缝中生存找解决方案. 这无异于早些年 JS 的 升级过程, 需要颠覆性产品不断涌现, 比如腾讯, 百度提出的小程序生态. 这是一个需要时间的过程... 持续关注.
参考文档
[Android] Scheme 详解
iOS9 Universal Links http://strivingboy.github.io/blog/2015/09/27/ios9/
Universal Link 前端部署采坑记 http://www.cocoachina.com/ios/20170904/20463.html
欢迎留言沟通交流. 如有需要转载或者引用, 辛苦标注一下, 互相帮助.
来源: https://juejin.im/post/5bea503ce51d454e2e1e75be