H5喚起APP指南(附開源喚端庫)

_拾邑發表於2018-08-24

前一段時間在做電流App H5頁面,需求中落地頁佔比較大,落地頁承擔的職責就是引流。引流有兩種形式,同時也是我們對喚端的定義:引導已下載使用者開啟APP,引導未下載使用者下載APP。

引導已下載使用者開啟APP,從資料上說使用者停留在APP中的時間更多了,是在提高使用者粘性;從體驗上說,APP體驗是要比H5好的。引導未下載使用者下載APP,可以增加我們的使用者量。

上面其實分別解釋了 什麼是喚端 以及 為什麼要喚端,也就是 3W法則 中的 What 和 Why,那麼接下來我們就要聊一聊 How 了,也就是 如何喚端

我們先來看看常見的喚端方式以及他們適用的場景:

喚端媒介

URL Scheme

來源

我們的手機上有許多私密資訊,聯絡方式、照片、銀行卡資訊…我們不希望這些資訊可以被手機應用隨意獲取到,資訊洩露的危害甚大。所以,如何保證個人資訊在裝置所有者知情並允許的情況下被使用,是智慧裝置的核心安全問題。

對此,蘋果使用了名為 沙盒 的機制:應用只能訪問它宣告可能訪問的資源。但沙盒也阻礙了應用間合理的資訊共享,某種程度上限制了應用的能力。

因此,我們急需要一個輔助工具來幫助我們實現應用通訊, URL Scheme 就是這個工具。

URL Scheme 是什麼

我們來看一下 URL 的組成:

[scheme:][//authority][path][?query][#fragment]複製程式碼

我們拿 https://www.baidu.com 來舉例,scheme 自然就是 https 了。

就像給伺服器資源分配一個 URL,以便我們去訪問它一樣,我們同樣也可以給手機APP分配一個特殊格式的 URL,用來訪問這個APP或者這個APP中的某個功能(來實現通訊)。APP得有一個標識,好讓我們可以定位到它,它就是 URL 的 Scheme 部分。

常用APP的 URL Scheme

APP 微信 支付寶 淘寶 微博 QQ 知乎 簡訊
URL Scheme weixin:// alipay:// taobao:// sinaweibo:// mqq:// zhihu:// sms://

URL Scheme 語法

上面表格中都是最簡單的用於開啟 APP 的 URL Scheme,下面才是我們常用的 URL Scheme 格式:

     行為(應用的某個功能)                |scheme://[path][?query]   |               |應用標識       功能需要的引數複製程式碼

Intent

安卓的原生谷歌瀏覽器自從 chrome25 版本開始對於喚端功能做了一些變化,URL Scheme 無法再啟動Android應用。 例如,通過 iframe 指向 weixin://,即使使用者安裝了微信也無法開啟。所以,APP需要實現谷歌官方提供的 intent: 語法,或者實現讓使用者通過自定義手勢來開啟APP,當然這就是題外話了。

Intent 語法

intent:   HOST/URI-path // Optional host    #Intent;
package=[string];
action=[string];
category=[string];
component=[string];
scheme=[string];
end;
複製程式碼

如果使用者未安裝 APP,則會跳轉到系統預設商店。當然,如果你想要指定一個喚起失敗的跳轉地址,新增下面的字串在 end;
前就可以了:

S.browser_fallback_url=[encoded_full_url]複製程式碼

示例

下面是開啟 Zxing 二維碼掃描 APP 的 intent。

intent:   //scan/   #Intent;
package=com.google.zxing.client.android;
scheme=zxing;
end;
複製程式碼

開啟這個 APP ,可以通過如下的方式:

 <
a href="intent://scan/#Intent;
scheme=zxing;
package=com.google.zxing.client.android;
S.browser_fallback_url=http%3A%2F%2Fzxing.org;
end"
>
Take a QR code <
/a>
複製程式碼

Universal Link

Universal Link 是什麼

Universal Link 是蘋果在 WWDC2015 上為 iOS9 引入的新功能,通過傳統的 HTTP 連結即可開啟 APP。如果使用者未安裝 APP,則會跳轉到該連結所對應的頁面。

為什麼要使用 Universal Link

傳統的 Scheme 連結有以下幾個痛點:

  • 在 ios 上會有確認彈窗提示使用者是否開啟,對於使用者來說喚端,多出了一步操作。若使用者未安裝 APP ,也會有一個提示窗,告知我們 “打不開該網頁,因為網址無效”
  • 傳統 Scheme 跳轉無法得知喚端是否成功,Universal Link 喚端失敗可以直接開啟此連結對應的頁面
  • Scheme 在微信、微博、QQ瀏覽器、手百中都已經被禁止使用,使用 Universal Link 可以避開它們的遮蔽( 截止到 18年8月21日,微信和QQ瀏覽器已經禁止了 Universal Link,其他主流APP未發現有禁止 )

如何讓 APP 支援 Universal Link

有大量的文章會詳細的告訴我們如何配置,你也可以去看官方文件,我這裡簡單的寫一個12345。

  1. 擁有一個支援 https 的域名
  2. 開發者中心 ,Identifiers 下 AppIDs 找到自己的 App ID,編輯開啟 Associated Domains 服務。
  3. 開啟工程配置中的 Associated Domains ,在其中的 Domains 中填入你想支援的域名,必須以 applinks: 為字首
  4. 配置 apple-app-site-association 檔案,檔名必須為 apple-app-site-association不帶任何字尾
  5. 上傳該檔案到你的 HTTPS 伺服器的 根目錄 或者 .well-known 目錄下

Universal Link 配置中的坑

這裡放一下我們在配置過程中遇到的坑,當然首先你在配置過程中必須得嚴格按照上面的要求去做,尤其是加粗的地方。

  1. 跨域問題

    IOS 9.2 以後,必須要觸發跨域才能支援 Universal Link 喚端。

    IOS 那邊有這樣一個判斷,如果你要開啟的 Universal Link 和 當前頁面是同一域名,ios 尊重使用者最可能的意圖,直接開啟連結所對應的頁面。如果不在同一域名下,則在你的 APP 中開啟連結,也就是執行具體的喚端操作。

  2. Universal Link 是空頁面

    Universal Link 本質上是個空頁面,如果未安裝 APP,Universal Link 被當做普通的頁面連結,自然會跳到 404 頁面,所以我們需要將它繫結到我們的中轉頁或者下載頁。

如何呼叫三種喚端媒介

通過前面的介紹,我們可以發現,無論是 URL Scheme 還是 Intent 或者 Universal Link ,他們都算是 URL ,只是 URL Scheme 和 Intent 算是特殊的 URL。所以我們可以拿使用 URL 的方法來使用它們。

iframe

<
iframe src="sinaweibo://qrcode">
複製程式碼

在只有 URL Scheme 的日子裡,iframe 是使用最多的了。因為在未安裝 app 的情況下,不會去跳轉錯誤頁面。但是 iframe 在各個系統以及各個應用中的相容問題還是挺多的,不能全部使用 URL Scheme。

a 標籤

<
a href="intent://scan/#Intent;
scheme=zxing;
package=com.google.zxing.client.android;
end"
">
掃一掃<
/a>
複製程式碼

前面我們提到 Intent 協議,官方給出的用例使用的就是使用的 a 標籤,所以我們跟著一起用就可以了

使用過程中,對於動態生成的 a 標籤,使用 dispatch 來模擬觸發點選事件,發現很多種 event 傳遞過去都無效;使用 click() 來模擬觸發,部分場景下存在這樣的情況,第一次點選過後,回到原先頁面,再次點選,點選位置和頁面所識別位置有不小的偏移,所以 Intent 協議從 a 標籤換成了 window.location。

window.location

URL Scheme 在 ios 9+ 上諸如 safari、UC、QQ瀏覽器中, iframe 均無法成功喚起 APP,只能通過 window.location 才能成功喚端。

當然,如果我們的 app 支援 Universal Link,ios 9+ 就用不到 URL Scheme 了。而 Universal Link 在使用過程中,我發現在 qq 中,無論是 iframe 導航 還是 a 標籤開啟 又或者 window.location 都無法成功喚端,一開始我以為是 qq 和微信一樣禁止了 Universal Link 喚端的功能,其實不然,百般試驗下,通過 top.location 喚端成功了。

判斷喚端是否成功

如果喚端失敗(APP 未安裝),我們總是要做一些處理的,可以是跳轉下載頁,可以是 ios 下跳轉 App Store… 但是Js 並不能提供給我們獲取 APP 喚起狀態的能力,Android Intent 以及 Universal Link 倒是不用擔心,它們倆的自身機制允許它們喚端失敗後直接導航至相應的頁面,但是 URL Scheme 並不具備這樣的能力,所以我們只能通過一些很 hack 的方式來實現 APP 喚起檢測功能。

// 一般情況下是 visibilitychange const visibilityChangeProperty = getVisibilityChangeProperty();
const timer = setTimeout(() =>
{
const hidden = isPageHidden();
if (!hidden) {
cb();

}
}, timeout);
if (visibilityChangeProperty) {
document.addEventListener(visibilityChangeProperty, () =>
{
clearTimeout(timer);

});
return;

}window.addEventListener('pagehide', () =>
{
clearTimeout(timer);

});
複製程式碼

APP 如果被喚起的話,頁面就會進入後臺執行,會觸發頁面的 visibilitychange 事件。如果觸發了,則表明頁面被成功喚起,及時呼叫 clearTimeout ,清除頁面未隱藏時的失敗函式(callback)回撥。

當然這個事件是有相容性的,具體的程式碼實現時做了事件是否需要新增字首(比如 -webkit- )的校驗。如果都不相容,我們將使用 pagehide 事件來做兜底處理。

沒有完美的方案

透過上面的幾個點,我們可以發現,無論是 喚端媒介呼叫喚端媒介 還是 判斷喚端結果 都沒有一個十全十美的方法,我們在程式碼層上能做的只是在確保最常用的場景(比如 微信、微博、手百 等)喚端無誤的情況下,最大化的相容剩餘的場景。

好的,我們接下來扯一些程式碼以外的,讓我們的 APP 能夠在更多的平臺喚起。

  • 微信、微博、手百、QQ瀏覽器等。

    這些應用能阻止喚端是因為它們直接遮蔽掉了 URL Scheme 。接下來可能就有看官疑惑了,微信中是可以開啟大眾點評的呀,微博裡面可以開啟優酷呀,那是如何實現的呢?

    它們都各自維護著一個白名單,如果你的域名在白名單內,那這個域名下所有的頁面發起的 URL Scheme 就都會被允許。就像微信,如果你是騰訊的“家屬”,你就可以加入白名單了,微信的白名單一般只包含著“家屬”,除此外很難申請到白名單資質。但是微博之類的都是可以聯絡他們的渠道童鞋進行申請的,只是條件各不相同,比如微博的就是在你的 APP 中新增開啟微博的入口,三個月內喚起超過 100w 次,就可以加入白名單了。

  • 騰訊應用寶直接開啟 APP 的某個功能

    剛剛我們說到,如果你不是微信的家屬,那你是很難進入白名單的,所以在安卓中我們一般都是直接開啟騰訊應用寶,ios 中 直接開啟 App Store。點選騰訊應用寶中的“開啟”按鈕,可以直接喚起我們的 APP,但是無法開啟 APP 中的某個功能(就是無法開啟指定頁面)。

    騰訊應用寶對外開放了一個叫做 APP Link 的申請,只要你申請了 APP Link,就可以通過在開啟應用寶的時候在應用寶地址後面新增上 &
    android_schema={your_scheme
    }
    ,來開啟指定的頁面了。

開箱即用的callapp-lib

資訊量很大!各種問題得自己趟坑驗證!內心很崩潰!

不用愁,已經為你準備好了藥方,只需照方抓藥即可? —— npm 包 callapp-lib

你也可以通過 script 直接載入 cdn 檔案:

<
script src="https://unpkg.com/callapp-lib">
<
/script>
複製程式碼

它能在大部分的環境中成功喚端,而且炒雞簡單啊,拿過去就可以用啊,還支援很多擴充套件功能啊,快來瞅瞅它的 文件 啊~~~

參考文章

  1. 瀏覽器中喚起 native app,否則跳轉到應用商城下載
  2. h5喚起app
  3. URL Schemes 使用詳解
  4. Android Intents with Chrome
  5. 常用URL Scheme
  6. Universal Link 前端部署採坑記
  7. Support Universal Links
  8. Universal Link是個騙子

本文首發於:suanmei.github.io/2018/08/23/…

來源:https://juejin.im/post/5b7efb2ee51d45388b6af96c

相關文章