h5唤醒app,有两种方式,第一种就是设置简单的URLSchemes,另一种是使用Universal Links深度连接.
然而对于ios来说,第一种方法,我们在safari浏览器打开,完全可以,然而,如果分享链接在qq和微信,就不能唤起app了,还需要提示用户通过safari打开,这种用户体验很差劲. 原因是,现在微信APP,已经对外封杀了使用schema自定义协议头的方式来打开第三方公司APP的接口,除非第三方公司是微信的合作伙伴,进行合作提供接口来实现,这时候是用到了深度连接.深度连接是通过一个双方协定好的https请求来打开页面的,可以完美的绕过微信和QQ内置浏览器的规则.
使用Universal Links,第一步,首先把一个名字为apple-app-site-association的文件,放置在一个域名的根目录,我们可以通过https://host/apple-app-site-association浏览器可以下载.(其实不必非要在根目录,别的目录也可以,然后做个映射,只要能使用https://host/apple-app-site-association这种连接下载即可),文件内容如下:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "teamId.boundleId",//开发者账号中的teamId+app的boundleId
"paths":[ "*" ] //键设定一个你的app支持的路径列表,只有这些指定的路径的链接才能唤起app,*表示全部
}
]
}
}
这一步做好之后,接下来,需要ios添加配置,支持Universal Links
这里填写的域名是apple-app-site-association文件所在的域名,当你第一次运行app的时候,app会将apple-app-site-association从服务器下载下来.这样当我们打开链接的时候,就可以唤醒app了.
这时候,一切完成之后,我们把连接发送到微信,点击,即可完成app唤醒,现在已经完成了一半了.现在app存在的已经完成,那么如果不存在又怎么办呢.网上写的方式是,写上一个定时器,首先跳转唤醒app的url,等2S之后再跳转下载app的链接,这样,如果2S之后,未唤醒app就说明,没有安装,然后这种方法太low了,而且,会出现这种状况,app存在,点击链接唤醒app,点返回键,会出现下载页,这很不好,不完美.我们知道,我们打开一个地址比如.https://demo.com/app/这时候,默认打开的就是存在服务端的app文件夹路径下的index.html网页.我们可以使用这点,通过一个连接自动判断,是否安装app.比如,我们上面定义的唤醒app的路径为https://demo.com/app/ 我们在app文件夹下放一个index.html页面,页面只写一个js,进入这个页面即跳转到下载页面.这样,如果app存在,通过https://demo.com/app/可唤醒app,不存在可自动进入下载页面.
这样我们已经实现了一个连接,完美唤醒app了.然而这样还不够,因为实际开发中,我们不会直接分享唤醒app的链接,一般都是分享一个页面,页面上有某个按钮,点击按钮跳转app.这时候又是一个坑,注意:分享页面的域名不能和唤醒app的域名一致.否则不会唤醒app.我们可以把分享页面部署在一个域名下,唤醒app的apple-app-site-association文件和下载app的index.html页面放在另一个域名或者,在使用一个二级域名,两个域名指向同一个地址.
对于安卓来说,使用URLSchemes就可以了,如果想使用深度连接,安卓也是需要一个文件,不同的是,ios的下载文件不能加.json后缀,安卓的需要加后缀.别的都和ios一样.
安卓如果使用URLSchemes,也有个坑,就是上面提的使用定时器唤醒下载页,如果app存在,一样体验不好,这里顺便分享一下,使用URLSchemes时,检测app是否存在的方法
function CallApp(url) {
var timeout, t = 1000, hasApp = true;
setTimeout(function () {
if (hasApp) {
window.location.replace(url);
} else {
window.location.replace("下载页");
}
document.body.removeChild(ifr);
}, 2000)
var t1 = Date.now();
var ifr = document.createElement("iframe");
ifr.setAttribute('src', url);
ifr.setAttribute('style', 'display:none');
document.body.appendChild(ifr);
timeout = setTimeout(function () {
var t2 = Date.now();
if (!t1 || t2 - t1 < t + 100) {
hasApp = false;
}
}, t);
}
总结知识查漏补缺,如有不足或错误,欢迎大神补充指正.在此谢过.