喚起 App 應該是很常見的問題了。我們在開發 H5 的時候,有一些鏈路上的功能在 H5 不支持,只能去 App 才能完成。比如,下單、支付等功能。那麼在更多的場景能夠喚起 App 就顯得很重要了。
-
判斷瀏覽器,動態加載對應瀏覽器的下載邏輯
-
通過
universal link
、URL Scheme
、a 標籤
、iframe
幾種方式找出最適合這個瀏覽器的喚起方式。 -
如果下載了 App,就會走打開邏輯,如果沒有下載則走下載邏輯。
-
如果已知不能喚起的瀏覽器引導其它瀏覽器打開
各個喚起方法對比
沒有哪種方式是完美的,每種喚起方式都有它的優勢跟劣勢,只有將所有的喚起方法在不同瀏覽器上嘗試過才能擇優使用。
通用鏈接(universal link)
通用鏈接
universal link
是IOS 9.0
版本以上纔可以使用的新的特性。此特性類似於深層鏈接,並能夠方便地通過打開一個https
鏈接來直接啓動您的客戶端應用(手機有安裝 App)。對比起以往所使用的URL Scheme
, 這種新特性在實現web-app
的無縫鏈接時能夠提供極佳的用戶體驗。
體驗一下通用鏈接
我們可以來體驗一下,左邊的是通用鏈接 universal link
方式,右邊是 URL Scheme
方式。
左邊可以直接將 App 打開,而右邊需要確認是否打開纔可以。
解決的bug
:在 ios 12.3
版本之後,Safari
會有一個 bug,就是 URL Scheme
跟 download App
先後一起使用的話,會同時喚起 App
然後再進入 App store
,體驗極差。使用 universal link
可以完美解決這個問題。
通用鏈接配置
必須在根目錄下或者 域名/.well-known 下面。注意
域名不要使用業務域名添加配置文件,必須要跨域使用,否則會會不能喚起App,直接打開頁面。
-
訪問鏈接
我們假設有三個 App,分別是appa
、appb
、appc
,我們通過訪問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": ["*"]
}
]
}
}
通用鏈接的優缺點:
-
優點
:提供極佳的用戶體驗,使用起來也非常方便,解決了同時喚起app
跟app store
的問題 -
缺點
:只有在 ios 9 版本之上才能使用,個別瀏覽器不支持有兼容性問題
URL Scheme 方式
根據協議來判斷是哪個 app 喚起。
location.href = "testa://cainiaoqianduan.com";
判斷是否喚起 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);
優缺點
//微信 必須配置白名單,或者使用 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);
//百度瀏覽器必須用 universal link 方式才能在 IOS 喚起
//qq 在 ios 要使用 a 標籤 的方式,即使通用鏈接的方式也不能將其喚起
if (isIOS) {
const a = document.createElement("a");
a.setAttribute("href", __SCHEMA_PATH);
return a.click();
}
location.href = __SCHEMA_PATH;
//微博,測試京東跟淘寶都可以調起,猜測是設置了白名單,目前沒有找到好的辦法,只能引導到其它瀏覽器中打開
目前只有微博不能喚起,其它都可以正常喚起
場景 | ios | 安卓 | 是否需要配置白名單 |
---|---|---|---|
微信 | ✔️ | ✔️ | 是 |
✔️ | ✔️ | 否 | |
chrome | ✔️ | ✔️ | 否 |
小米 browser | ✔️ | ✔️ | 否 |
uc | ✔️ | ✔️ | 否 |
qq browser | ✔️ | ✔️ | 否 |
360 browser | ✔️ | ✔️ | 否 |
獵豹 | ✔️ | ✔️ | 否 |
sogou | ✔️ | ✔️ | 否 |
baidu browser | ✔️ | ✔️ | 否 |
safari | ✔️ | ✔️ | 否 |
微博 | X | X | 是 |