首先,简述一下这个需求的背景,产品希望能够让用户在微信内,打开一个h5页面,然后就能唤醒公司中维护的app,这个是为了能够更好的引流。
唤醒app的方案
IOS系统-Universal Link(通用链接)
Universal Links可以通过配置指定域名路径直接唤醒APP,一步到位
具体配置看这篇文章
https://juejin.cn/post/6937614343840202766
遇到的问题:
{ "applinks": { "apps": [], "details": [ { "appID": "******", "paths": [ "/abc/*" ] }, ] } }
使用Universal Link其实就是跳转到一个页面(中间页),地址:https://my.app.com/abc/index.html
根据上面配置,这个地址是已经固定了的,这需要跟app域名保持一致,并且在paths配置里面的目录下,为了能够获取到apple-app-site-association文件
const universalLink = 'https://my.app.com/abc/index.html?redirectUrl=' + window.location.href location.replace(universalLink);
如果未下载app,则会跳转失败,在中间页中处理,跳转失败后再返回到当前页面。
<script> function getQueryStringArgs(url, opt) { const { decode = true, multiple = false } = opt || {}; const args = {}; if (!(typeof url === 'string' && url.includes('?'))) return args; const arr = url.split('?'); const qs = arr.length === 2 ? arr[1] : ''; if (!(typeof qs === 'string' && qs.length)) return args; const items = qs.split('&'); for (let i = 0; i < items.length; i++) { const meta = items[i]; if (!(typeof meta === 'string' && meta.includes('='))) continue; const item = meta.split('='); const key = decode ? decodeURIComponent(item[0]) : item[0]; const value = decode ? decodeURIComponent(item[1]) : item[1]; if (Object.prototype.hasOwnProperty.call(args, key) && multiple) { const temp = args[key]; args[key] = Array.isArray(temp) ? [...temp, value] : [temp, value]; } else { args[key] = value; } } return args; } const { redirectUrl } = getQueryStringArgs(location.href) if (typeof redirectUrl === 'string' && redirectUrl) { location.replace(redirectUrl + '?callType=universalLink') // 处理唤醒app失败场景 } </script>
上面这段逻辑如果直接放在html中,最好先手动转一下ES5语法,然后压缩一下,这样兼容性好,上面这样展示,是为了可读性好。
总结:
ios系统使用Universal Link在微信和浏览器内都能够正常的唤醒App,且兼容性比较好。但是需要注意中间页域名需要跟app域名保持一致;唤醒app的h5链接域名不能跟中间页域名一致。
直接扫二维码进入另一个页面,需要进行点击操作才能跳转,IOS不允许打开页面立刻就跳转。
URL-Schemes
URL scheme是App提供给外部的可以直接操作App的规则。
比如微信提供了打开扫一扫的URL scheme。weixin://dl/scan
比如支付宝提供了转账的URL scheme。alipayqr://platformapi/startapp?saId=20000116
比如知乎提供了打开回答页面的URL scheme。zhihu://answers/{id}
如何找到某个app的URL Scheme呢?可以看下面这篇文章
https://zhuanlan.zhihu.com/p/53439246
安卓唤醒app呢,就是使用这种方式
比如:安卓开发提供的是
那跳转的链接是什么样的呢?
const schemeURL = 'myapp://www.myapp.apk' window.href = schemeURL;
如何判断唤醒失败呢?
没有什么好办法来判断,后面只能触发了唤醒操作之后,监听页面几秒之后是否隐藏来判断,目前默认是2秒
export function getSupportedProperty() { let hidden; let visibilityChange; if (typeof document.hidden !== 'undefined') { // Opera 12.10 and Firefox 18 and later support hidden = 'hidden'; visibilityChange = 'visibilitychange'; // @ts-ignore } else if (typeof document.msHidden !== 'undefined') { hidden = 'msHidden'; visibilityChange = 'msvisibilitychange'; // @ts-ignore } else if (typeof document.webkitHidden !== 'undefined') { hidden = 'webkitHidden'; visibilityChange = 'webkitvisibilitychange'; } return { hidden, visibilityChange, }; } /** * 判断页面是否隐藏(进入后台) */ export function isPageHidden() { const ob = getSupportedProperty(); const hidden = ob?.hidden; if (typeof hidden === 'undefined') return false; // @ts-ignore return document[hidden]; } /** * 检测是否唤端成功 * 在唤起执行后,当前页面调用此方法根据页面隐藏变化检测是否唤醒成功 * @param {number} timeout 定时时间,默认2秒 * @return {Object} Promise对象 */ export function checkOpen(timeout = 2000) { return new Promise((resolve, reject) => { const ob = getSupportedProperty(); const visibilityChange = ob?.visibilityChange; const check = () => { const pageHidden = isPageHidden(); if (pageHidden) { resolve(); // 页面被隐藏,说明唤醒成功 } else { reject(new Error('唤醒超时')); } }; const timer = setTimeout(() => { check(); }, timeout); const fn = () => { if (typeof visibilityChange !== 'undefined') { document.removeEventListener(visibilityChange, fn); } else { window.removeEventListener('pagehide', fn); } check(); // 唤醒执行后,立马触发页面隐藏变化,可检测是否唤醒成功 clearTimeout(timer); // 未到达指定时间,页面隐藏变化,清除定时器 }; if (typeof visibilityChange !== 'undefined') { document.addEventListener(visibilityChange, fn); } else { window.addEventListener('pagehide', fn); } }); }
总结:
安卓使用URL Schemes在微信中是不能跳转的,在浏览器中是能够正常拉起。
还木有评论哦,快来抢沙发吧~