首先,簡(jiǎn)述一下這個(gè)需求的背景,產(chǎn)品希望能夠讓用戶(hù)在微信內(nèi),打開(kāi)一個(gè)h5頁(yè)面,然后就能喚醒公司中維護(hù)的app,這個(gè)是為了能夠更好的引流。
喚醒a(bǔ)pp的三種方案
IOS系統(tǒng)-Universal Link(通用鏈接)
Universal Links可以通過(guò)配置指定域名路徑直接喚醒APP,一步到位
具體配置看這篇文章
https://juejin.cn/post/6937614343840202766
遇到的問(wèn)題:
apple-app-site-association文件放在app域名(假設(shè): https://my.app.com/)下
{
"applinks": {
"apps": [],
"details": [
{
"appID": "******",
"paths": [ "/abc/*" ]
},
]
}
}
使用Universal Link其實(shí)就是跳轉(zhuǎn)到一個(gè)頁(yè)面(中間頁(yè)),地址:https://my.app.com/abc/index.html
根據(jù)上面配置,這個(gè)地址是已經(jīng)固定了的,這需要跟app域名保持一致,并且在paths配置里面的目錄下,為了能夠獲取到apple-app-site-association文件
const universalLink = 'https://my.app.com/abc/index.html?redirectUrl=' + window.location.href
location.replace(universalLink);
如果未下載app,則會(huì)跳轉(zhuǎn)失敗,在中間頁(yè)中處理,跳轉(zhuǎn)失敗后再返回到當(dāng)前頁(yè)面。
<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') // 處理喚醒a(bǔ)pp失敗場(chǎng)景
}
</script>
上面這段邏輯如果直接放在html中,最好先手動(dòng)轉(zhuǎn)一下ES5語(yǔ)法,然后壓縮一下,這樣兼容性好,上面這樣展示,是為了可讀性好。
總結(jié):
ios系統(tǒng)使用Universal Link在微信和瀏覽器內(nèi)都能夠正常的喚醒App,且兼容性比較好。但是需要注意中間頁(yè)域名需要跟app域名保持一致;喚醒a(bǔ)pp的h5鏈接域名不能跟中間頁(yè)域名一致。
直接掃二維碼進(jìn)入另一個(gè)頁(yè)面,需要進(jìn)行點(diǎn)擊操作才能跳轉(zhuǎn),IOS不允許打開(kāi)頁(yè)面立刻就跳轉(zhuǎn)。
URL-Schemes
URL scheme是App提供給外部的可以直接操作App的規(guī)則。
- 比如微信提供了打開(kāi)掃一掃的URL scheme。weixin://dl/scan
- 比如支付寶提供了轉(zhuǎn)賬的URL scheme。alipayqr://platformapi/startapp?saId=20000116
- 比如知乎提供了打開(kāi)回答頁(yè)面的URL scheme。zhihu://answers/{id}
如何找到某個(gè)app的URL Scheme呢?可以看下面這篇文章
https://zhuanlan.zhihu.com/p/53439246
安卓喚醒a(bǔ)pp呢,就是使用這種方式
比如:安卓開(kāi)發(fā)提供的是
那跳轉(zhuǎn)的鏈接是什么樣的呢?
const schemeURL = 'myapp://www.myapp.apk'
window.href = schemeURL;
如何判斷喚醒失敗呢?
沒(méi)有什么好辦法來(lái)判斷,后面只能觸發(fā)了喚醒操作之后,監(jiān)聽(tīng)頁(yè)面幾秒之后是否隱藏來(lái)判斷,目前默認(rèn)是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,
};
}
/**
* 判斷頁(yè)面是否隱藏(進(jìn)入后臺(tái))
*/
export function isPageHidden() {
const ob = getSupportedProperty();
const hidden = ob?.hidden;
if (typeof hidden === 'undefined') return false;
// @ts-ignore
return document[hidden];
}
/**
* 檢測(cè)是否喚端成功
* 在喚起執(zhí)行后,當(dāng)前頁(yè)面調(diào)用此方法根據(jù)頁(yè)面隱藏變化檢測(cè)是否喚醒成功
* @param {number} timeout 定時(shí)時(shí)間,默認(rèn)2秒
* @return {Object} Promise對(duì)象
*/
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(); // 頁(yè)面被隱藏,說(shuō)明喚醒成功
} else {
reject(new Error('喚醒超時(shí)'));
}
};
const timer = setTimeout(() => {
check();
}, timeout);
const fn = () => {
if (typeof visibilityChange !== 'undefined') {
document.removeEventListener(visibilityChange, fn);
} else {
window.removeEventListener('pagehide', fn);
}
check(); // 喚醒執(zhí)行后,立馬觸發(fā)頁(yè)面隱藏變化,可檢測(cè)是否喚醒成功
clearTimeout(timer); // 未到達(dá)指定時(shí)間,頁(yè)面隱藏變化,清除定時(shí)器
};
if (typeof visibilityChange !== 'undefined') {
document.addEventListener(visibilityChange, fn);
} else {
window.addEventListener('pagehide', fn);
}
});
}
總結(jié):
安卓使用URL Schemes在微信中是不能跳轉(zhuǎn)的,在瀏覽器中是能夠正常拉起。
微信開(kāi)放標(biāo)簽
由于在微信環(huán)境內(nèi),所以可以使用微信提供的能力來(lái)喚醒a(bǔ)pp,微信內(nèi)禁止使用URL Schemes喚醒a(bǔ)pp,其實(shí)就是微信的一種保護(hù)機(jī)制。
微信文檔:
https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_H5_Launch_APP.html
如上圖,使用這個(gè)功能,有很多限制,而且需要配置,但是為了安卓用戶(hù)成功引流,產(chǎn)品還是要求使用這個(gè)功能。
微信配置
1.關(guān)聯(lián)App-微信開(kāi)發(fā)平臺(tái)
微信開(kāi)發(fā)平臺(tái)配置關(guān)聯(lián)App,關(guān)聯(lián)App需要appId,已經(jīng)有App的域名
微信開(kāi)發(fā)平臺(tái)地址: https://open.weixin.qq.com/
2.H5頁(yè)面域名配置-微信公眾平臺(tái)
JS安全域名需要配置當(dāng)前h5頁(yè)面的域名
微信公眾號(hào)地址: https://mp.weixin.qq.com/
3.初始化微信SDK,需要獲取簽名
微信開(kāi)發(fā)SDK文檔
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
這需要后端開(kāi)發(fā)接口, 去獲取簽名
使用微信開(kāi)放標(biāo)簽說(shuō)明:
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html
async getWxSignatureData() {
const url = window.location.href.split('#')[0];
const res = await getJsapiSignParamers(url);
const { appId, signature, timestamp, nonceStr } = res.data;
wx.config({
debug: false,
appId: appId,
timestamp: timestamp,
nonceStr: nonceStr,
signature: signature,
jsApiList: ['showOptionMenu'], // 必填,故使用一個(gè)非實(shí)際使用的api用于填充
openTagList: ['wx-open-launch-app'], // 可選,需要使用的開(kāi)放標(biāo)簽列表
});
wx.ready(() => {
console.info('wx sdk ready');
console.info('調(diào)用接口初始化wx sdk 成功');
this.initWxSDKStatus = 'success';
});
wx.error(res => {
console.error('調(diào)用接口初始化wx sdk 失敗', res);
this.initWxSDKStatus = 'fail';
});
},
接口返回的就是這樣的數(shù)據(jù)結(jié)構(gòu)
只有這樣才能正常初始化微信的SDK,只有正常初始化SDK才能夠使用微信開(kāi)放標(biāo)簽的能力。
然后后端開(kāi)發(fā)的時(shí)候要注意:簽名需要后端配置白名單ip,文檔說(shuō)明如下:
https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
安卓手機(jī),如果出現(xiàn)喚醒a(bǔ)pp之后,打開(kāi)了應(yīng)用,但是并未成功喚起,那是因?yàn)锳ndroid應(yīng)用有要求,需要安卓開(kāi)發(fā)兼容一下就行了~
微信環(huán)境內(nèi)場(chǎng)景
接下來(lái)就分析一下,在微信中有幾種分享的場(chǎng)景:
1.微信好友之間鏈接分享
這種方式,使用微信標(biāo)簽是不能喚醒App的,除非是在關(guān)注公眾號(hào)里面,這個(gè)公眾號(hào)就是上面綁定了JS安全域名的公眾號(hào)
這樣點(diǎn)擊這個(gè)鏈接就能正常用微信標(biāo)簽喚醒
2.微信好友之間卡片分享
這種點(diǎn)擊打開(kāi)是能夠正常喚醒App的,而且不需要使用公眾號(hào),但是這種分享有限制,需要打開(kāi)頁(yè)面點(diǎn)擊右上角分享給其他好友會(huì)帶上卡片形式,如果在瀏覽器中就只是復(fù)制鏈接了,微信不會(huì)自動(dòng)識(shí)別成卡片
而且這個(gè)分享其實(shí)就是微信的一個(gè)功能
https://developers.weixin.qq.com/minigame/dev/api/share/wx.onShareAppMessage.html
3.長(zhǎng)按識(shí)別二維碼識(shí)別H5鏈接
這種也能正常喚醒App,而且不需要關(guān)注公眾號(hào),也很方便,不需要將鏈接分享給其他人,只需要將喚醒App的鏈接做出二維碼就行了。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-743494.html
全部流程圖
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-743494.html
到了這里,關(guān)于微信內(nèi)H5頁(yè)面喚醒App的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!