查看原文
其他

各种场景唤起 App 骚操作

The following article is from 前端技匠 Author 罗学

唤起 App 应该是很常见的问题了。我们在开发 H5 的时候,有一些链路上的功能在 H5 不支持,只能去 App 才能完成。比如,下单、支付等功能。那么在更多的场景能够唤起 App 就显得很重要了。

几步走

  1. 判断浏览器,动态加载对应浏览器的下载逻辑
  2. 通过 universal linkURL Schemea 标签iframe 几种方式找出最适合这个浏览器的唤起方式。
  3. 如果下载了 App,就会走打开逻辑,如果没有下载则走下载逻辑。
  4. 如果已知不能唤起的浏览器引导其它浏览器打开

流程:

各个唤起方法对比

没有哪种方式是完美的,每种唤起方式都有它的优势跟劣势,只有将所有的唤起方法在不同浏览器上尝试过才能择优使用。

通用链接(universal link)

通用链接 universal linkIOS 9.0 版本以上才可以使用的新的特性。此特性类似于深层链接,并能够方便地通过打开一个 https 链接来直接启动您的客户端应用(手机有安装 App)。对比起以往所使用的 URL Scheme, 这种新特性在实现 web-app 的无缝链接时能够提供极佳的用户体验。

体验一下通用链接

我们可以来体验一下,左边的是通用链接 universal link方式,右边是 URL Scheme 方式。

左边可以直接将 App 打开,而右边需要确认是否打开才可以。


解决的bug:在 ios 12.3 版本之后,Safari 会有一个 bug,就是 URL Schemedownload App 先后一起使用的话,会同时唤起 App 然后再进入 App store,体验极差。使用 universal link 可以完美解决这个问题。

通用链接配置

必须在根目录下或者 域名/.well-known 下面。注意 域名不要使用业务域名添加配置文件,必须要跨域使用,否则会会不能唤起App,直接打开页面。

  • 访问链接 我们假设有三个 App,分别是 appaappbappc,我们通过访问 https://jump.test.com/appa/index.html 就可以唤起 appa 了。
  • 配置下载页 如果没有安装 appa 的话就会跳转到 一个 404 页面,因为我们这个页面 https://jump.test.com/appa/index.html 其实并不存在,所以我们需要将这个页面在 nginx 代理到一个下载页面。
  • 疑问 那么你可能有一个疑问,我如果唤起来 app 之后这个页面会不会跳转到下载页呢?答案是不会的,如果唤起了 app 就不会继续跳转页面了,只有在唤不起来的时候才会进入下载页。

apple-app-site-association 配置

{
"applinks": {
"apps": [],
"details": [
{
"appID": "ABCD.com.aaa.appa",
"paths": ["appa/*"]
},
{
"appID": "ABCD.com.aaa.appb",
"paths": ["appb/*"]
},
{
"appID": "ABCD.com.aaa.appc",
"paths": ["appc/*"]
},
{
"appID": "ABCD.com.aaa.*",
"paths": ["*"]
}
]
}
}

通用链接的优缺点:

  • 优点:提供极佳的用户体验,使用起来也非常方便,解决了同时唤起 appapp store 的问题
  • 缺点:只有在 ios 9 版本之上才能使用,个别浏览器不支持有兼容性问题

URL Scheme 方式

用法

根据协议来判断是哪个 app 唤起。

location.href = "testa://test.aaa.com/home";

判断是否唤起 app

因为唤起 app 并没有回调让我们知道唤起了 app,所以我们只能通过监听页面是否隐藏来实现判断是否唤起 app 的逻辑。当然这种做法还是有很大缺陷的,比如低端机型唤起速度很慢,高端机型要快得多,所以 delay 的时间要设置一个可以接受的值,我们暂时定的是 2500。还有如果用户没有安装 app,也会有 2500 的延时才能安装。

const timer = setTimeout(() => {
this.__download(options);
}, options.delay);

const visibilitychange = function() {
const tag = document.hidden || document.webkitHidden;
tag && clearTimeout(timer);
};

document.addEventListener("visibilitychange", visibilitychange, false);
document.addEventListener("webkitvisibilitychange", visibilitychange, false);
window.addEventListener(
"pagehide",
function() {
clearTimeout(timer);
},
false
);

URL Scheme 的优缺点:

  • 优点 1. 兼容性好,大部分机型都能兼容 2. 使用方便
  • 缺点 1. 不能判断是否已经下载了 app,需要自己写逻辑判断 2. 用户体验不如通用链接的方式。

a 标签跟 iframe 方式

这两种方式都是通过创建元素,通过元素属性的特性来做的

a 标签

const a = document.createElement("a");
a.setAttribute("href", __SCHEMA_PATH);
a.click();

iframe

const ifr = document.createElement("iframe");
iframe.src = path;
ifr.src = nativeUrl;
ifr.style.cssText = "display:none;border:0;width:0;height:0;";
document.body.appendChild(ifr);
setTimeout(function() {
document.body.removeChild(ifr);
}, 1000);

优缺点

  • 优点 在个别场景中如果发现唤起 app 有问题,可以尝试这两种。
  • 缺点 iframe 基本上已经被废弃了,a 标签测试结果只在个别机型中可用。

总结

  1. 微信 必须配置白名单,或者使用 universal link 也可以在 ios 唤起,表现形式有一点差别
const wxconfig = {
debug: false,
appId: conf.appId, // 公众号的 appid
timestamp: conf.timestamp,
nonceStr: conf.noncestr,
signature: conf.signature,
beta: true,
jsApiList: ["launchApplication", "getInstallState"]
};
(window.wx && window.wx.config(wxconfig)) || (window.wxconfig = wxconfig);
  1. 百度浏览器必须用 universal link 方式才能在 IOS 唤起
  2. qq 在 ios 要使用 a 标签 的方式,即使通用链接的方式也不能将其唤起
if (isIOS) {
const a = document.createElement("a");
a.setAttribute("href", __SCHEMA_PATH);
return a.click();
}
location.href = __SCHEMA_PATH;
  1. 微博,测试京东跟淘宝都可以调起,猜测是设置了白名单,目前没有找到好的办法,只能引导到其它浏览器中打开

测试结果

目前只有微博不能唤起,其它都可以正常唤起

场景ios安卓是否需要配置白名单
微信✔️✔️
qq✔️✔️
chrome✔️✔️
小米 browser✔️✔️
uc✔️✔️
qq browser✔️✔️
360 browser✔️✔️
猎豹✔️✔️
sogou✔️✔️
baidu browser✔️✔️
safari✔️✔️
微博XX

体验

AD:转转 App 是我们公司开发的 App,主要负责二手交易。可以通过下面的链接下载 转转App 来体验哦~

https://m.zhuanzhuan.com/common/pro_together_run_cli/index.html#/callApp

❤️爱心三连击

1.看到这里了就点个在看支持下吧,你的「在看」是我创作的动力。

2.关注公众号程序员成长指北「每天为您分享原创或精选文章」

3.特殊阶段,带好口罩,做好个人防护。

4.添加微信【ikoala520】,拉你进技术交流群一起学习。

在看和转发是莫大鼓励

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存