日常上圖.png

日常安利自己的Github,如果有錯(cuò)誤或者理解不正確的地方,麻煩告知我會(huì)及時(shí)更正。同時(shí)也非常歡迎大家一起討論。鞠躬。 Github地址:https://github.com/bsxz0604/RemarkForYouDontKnowJs (不定期更新...
背景
對(duì)于APP來(lái)說(shuō),回流分享頁(yè)是最好的最便宜的也是最病毒式的拉新方式。讓新用戶去下載APP是重要的。對(duì)老用戶來(lái)說(shuō),可以直接調(diào)起APP也是提升用戶體驗(yàn)和讓用戶有侵入式體驗(yàn)的重要手段。所以我們一起來(lái)看看有哪些方式可以喚起APP的
概念敘述
調(diào)起APP在不同平臺(tái)用不同的方式,主要就分3個(gè)
* URI Scheme
* universal Link
* Android App Links
現(xiàn)在還是有很多第三方來(lái)協(xié)助你處理這個(gè)事情,通過(guò)接入他們的SDK和客戶端代碼來(lái)處理,但是萬(wàn)變不離其宗,所有的第三方也離不開這3種方式。
- URI Scheme:
- URI Scheme 是iOS,Android平臺(tái)都支持,只需要原生APP開發(fā)時(shí)注冊(cè) scheme , 用戶點(diǎn)擊到此類鏈接時(shí),會(huì)自動(dòng)喚醒APP,借助于 URL Router 機(jī)制,則還可以跳轉(zhuǎn)至指定頁(yè)面。
- <scheme name> : <hierarchical part> [ ? <query> ] [ # <fragment> ]
- <scheme name>:是scheme的名稱,代表著協(xié)議名稱。
- <hierarchical part>:它包含 authority 和 path。
- <query>:可選項(xiàng)目,隔開或&隔開的鍵值對(duì)<key>=<value>
- <fragmentg> :可選項(xiàng)目包,其它額外的標(biāo)識(shí)信息
例如:
git://github.com/user/project-name.git
ftp://user1:1234@地址
scheme://xxxx?id=xxxx&key=xxxx
- universal Link:
- iOS9 后推出的一項(xiàng)功能,通用鏈接,對(duì)于前端即訪問(wèn)一個(gè)https的url,如果這個(gè)url帶有你提交給開發(fā)平臺(tái)的配置文件中匹配規(guī)則的內(nèi)容,iOS系統(tǒng)會(huì)去嘗試打開你的app,如果打不開,系統(tǒng)就會(huì)在瀏覽器中轉(zhuǎn)向你要訪問(wèn)的鏈接。
- universal Link 工作方式如下:
- 訪問(wèn)web link
- iOS訪問(wèn) https://xxxxxxx/apple-app-site-association 并解析,獲取文件中的信息(App的Team ID和Bundle ID)
- 通過(guò)Bundle ID 檢查本地是否存在對(duì)應(yīng)app,和檢查PATH信息等,如果有app打開app,如果沒(méi)有則跳轉(zhuǎn)對(duì)應(yīng)web link(可通過(guò)代碼實(shí)現(xiàn)跳去app Stroe)
- Android App Links:
- 在2015年的Google I/O大會(huì)上,Android M宣布了一個(gè)新特性:App Links讓用戶在點(diǎn)擊一個(gè)普通web鏈接的時(shí)候可以打開指定APP的指定頁(yè)面,前提是這個(gè)APP已經(jīng)安裝并且經(jīng)過(guò)了驗(yàn)證,否則會(huì)顯示一個(gè)打開確認(rèn)選項(xiàng)的彈出框,只支持Android M以上系統(tǒng)。
- 簡(jiǎn)單的說(shuō)就是建立APP和某個(gè)鏈接的關(guān)聯(lián),避免系統(tǒng)在處理該類型鏈接時(shí)彈出選擇框。彈框最常見(jiàn)的就是瀏覽器打開時(shí)的選擇框。彈出選擇框是應(yīng)用注冊(cè)了相應(yīng)scheme,applinks的作用是避免在打開自己域名的鏈接時(shí)彈出選擇(前提是注冊(cè)了相應(yīng)scheme),可以實(shí)現(xiàn)直接打開自己關(guān)聯(lián)的app。
對(duì)比/優(yōu)劣

- URI Scheme:
根據(jù)圖片可以看到URI Scheme的兼容性是最高,在使用的過(guò)程中,會(huì)發(fā)現(xiàn)有很多限制:- 當(dāng)要被喚起的app沒(méi)有安裝時(shí),這個(gè)鏈接就會(huì)出錯(cuò)。在國(guó)內(nèi)非常雜亂的瀏覽器中,會(huì)出錯(cuò)的現(xiàn)象會(huì)很多種類型。
- 當(dāng)注冊(cè)有多個(gè)scheme相同的時(shí)候,目前沒(méi)有辦法區(qū)分。
- 不支持從其他app中的UIWebView中跳轉(zhuǎn)到目標(biāo)app
也就因?yàn)闀?huì)有這些原因,apple和android都出現(xiàn)了自己第二套解決方案。
- universal Link 從鏈接上看來(lái),是一個(gè)web link,所以也就解決了當(dāng)沒(méi)有app時(shí),跳轉(zhuǎn)也不會(huì)出現(xiàn)報(bào)錯(cuò),所以相對(duì)Scheme優(yōu)勢(shì)就提現(xiàn)出來(lái)了.
- 當(dāng)已經(jīng)安裝app,不需要加載任何web頁(yè)面,app就會(huì)立即啟動(dòng);app沒(méi)有安裝,就會(huì)跳去對(duì)應(yīng)的web link。
- universal Link 是從服務(wù)器上查詢是哪個(gè)app需要被打開,所以不會(huì)存在沖突問(wèn)題
- universal Link 支持從其他app中的UIWebView中跳轉(zhuǎn)到目標(biāo)app
- 隱私性,提供universal Link給別的app進(jìn)行app間的交流,然而對(duì)方并不能夠用這個(gè)方法去檢測(cè)你的app是否被安裝。
當(dāng)然universal Link也不是十全十美的,缺陷也是存在的: -
會(huì)記住用戶的選擇:在用戶點(diǎn)擊了Universal link之后,iOS會(huì)去檢測(cè)用戶最近一次是選擇了直接打開app還是打開網(wǎng)站。一旦用戶點(diǎn)擊了這個(gè)選項(xiàng),他就會(huì)通過(guò)safiri打開你的網(wǎng)站。并且在之后的操作中,默認(rèn)一直延續(xù)這個(gè)選擇,除非用戶從你的webpage上通過(guò)點(diǎn)擊Smart App Banner上的OPEN按鈕來(lái)打開。
記住用戶的選擇.png
- app link 和 universal Link 差異不大。也是為了更好的提供調(diào)起app出現(xiàn)的google的方案。優(yōu)點(diǎn)與 universal Link 差不多,缺點(diǎn)主要如下:
- 國(guó)內(nèi)的支持相對(duì)較差,在有的瀏覽器或者手機(jī)ROM中并不能鏈接至APP,而是在瀏覽器中打開了對(duì)應(yīng)的鏈接。
- 在詢問(wèn)是否用APP打開對(duì)應(yīng)的鏈接時(shí),如果選擇了“取消”并且“記住選擇”被勾上,那么下次你再次想鏈接至APP時(shí)就不會(huì)有任何反應(yīng)

無(wú)論哪一種方式目前都沒(méi)有解決幾個(gè)問(wèn)題:
- 如果設(shè)備上沒(méi)有安裝這個(gè)app的時(shí)候,安裝完畢后,無(wú)法保留住此時(shí)用戶停留的上下文。
- 因?yàn)閣eb沒(méi)有辦法監(jiān)聽到APP是否安裝,所以都需要通過(guò)一些手段來(lái)兼容調(diào)起app或者是去下載頁(yè)
使用 & 需要注意的內(nèi)容
- URI Scheme:
- 使用: 這種方式是當(dāng)期使用最廣泛,也是最簡(jiǎn)單的,但是需要手機(jī),APP支持 URI Scheme 。
- 需要注意的內(nèi)容 & 遇到的問(wèn)題:
其實(shí)使用URI Scheme 部分前端沒(méi)有太多可以排查的問(wèn)題,會(huì)遇到的問(wèn)題主要是兩個(gè)部分。1. 在android的兼容性處理(國(guó)內(nèi)的瀏覽器無(wú)力吐槽ing),2. 當(dāng)沒(méi)有安裝app的情況,URI Scheme 會(huì)有各種報(bào)錯(cuò),也需要處理…
<!-- 喚醒APP并跳轉(zhuǎn)至指定的path頁(yè)面 -->
<a href="<scheme>://<path>?<params>=<value>">打開APP</a>
<!-- JS設(shè)置iframe src跳轉(zhuǎn)至指定的path頁(yè)面 -->
//創(chuàng)建一個(gè)隱藏的iframe
var ifr = document.createElement('iframe');
ifr.src = '<scheme>://<path>?<params>=<value>';
ifr.style.display = 'none';
document.body.appendChild(ifr);
//記錄喚醒時(shí)間
var openTime = +new Date();
window.setTimeout(function(){
document.body.removeChild(ifr);
//如果setTimeout 回調(diào)超過(guò)2500ms,則彈出下載
if( (+new Date()) - openTime > 2500 ){
window.location = '指定的下載頁(yè)面';
}
},2000)
- universal Link & app Links
- 使用:對(duì)于有app的用戶,只是打開一個(gè)連接,但是需要注意的是需要考慮到?jīng)]有APP的用戶。(個(gè)人的解決方案:針對(duì)域名來(lái)判斷,當(dāng)域名為特定的universal Link 的域名,則跳轉(zhuǎn)去下載頁(yè)面)
- 需要注意的內(nèi)容 & 遇到的問(wèn)題:
- apple-app-site-association 和 assetlinks.json 的配置
- 需要保證使用的鏈接跨域(universal Link)
- 直接將universal Link 貼入瀏覽器的url中不會(huì)生效
- window.onload 或者用戶沒(méi)有任何事件觸發(fā)的情況下,universal Link也不會(huì)生效
兩大平臺(tái)的特殊處理(facebook & twitter)
facebook 和 twitter 作為國(guó)外的兩大信息聚合平臺(tái),對(duì)于在他們app中調(diào)起app也有自己的一套方式。
根據(jù)要求通過(guò)添加META頭來(lái)處理打開APP
facebook:
<meta property="fb:app_id" content="xxxxxx" />
<meta property="og:type" content="xxxx"/>
<meta property="og:title" content="xxx" />
<meta property="al:ios:url" content="{{ uri scheme }}" />
<meta property="al:android:url" content="{{ uri scheme }}" />
<meta property="al:ios:app_store_id" content="{{app_store_id}}" />
<meta property="al:ios:app_name" content="{{xxx}}" />
<meta property="al:android:app_name" content="{{xxx}}" />
<meta property="al:android:package" content="{{android:package}}" />
twitter:
<meta name="twitter:card" content="app" />
<meta name="twitter:site" content="xxxxx" />
<meta name="twitter:title" content="xxxxx" />
<meta name="twitter:description" content="xxxxxxx" />
<meta name="twitter:image" content="xxxx" />
<meta name="twitter:app:name:iphone" content="xxx">
<meta name="twitter:app:id:iphone" content="xxx">
<meta name="twitter:app:url:iphone" content="{{Scheme}}">
<meta name="twitter:app:name:ipad" content="xxx">
<meta name="twitter:app:id:ipad" content="xxx">
<meta name="twitter:app:url:ipad" content="{{Scheme}}">
<meta name="twitter:app:name:googleplay" content="xxx">
<meta name="twitter:app:id:googleplay" content="xxx">
<meta name="twitter:app:url:googleplay" content="{{Scheme}}">
使用 checkList(前端)
-
scheme
- iOS 和 android 是否已經(jīng)支持 此scheme
- js處理兼容代碼
-
universal Link (apple-app-site-association 官方文檔)
- HTTPS的域名
- iOS9 以上
- universal Link 是否跨域
- universal Link的落地頁(yè)是否是下載頁(yè)面
- apple-app-site-association 配置在 host的根目錄和.well-known下
- 官方檢測(cè): apple-app-site-association 檢測(cè)
- apple-app-site-association會(huì)在第一次打開app或者更新app時(shí)候會(huì)去拉去,所以確認(rèn)是否更新了apple-app-site-association后沒(méi)有更新過(guò)app
- 檢查apple-app-site-association paths 大小寫敏感 支持通配符
- 該設(shè)備的用戶選擇了直接打開app還是打開網(wǎng)站,如果選擇打開網(wǎng)站,需要通過(guò)smart banner 重新啟用
- 跳轉(zhuǎn)處理是否是在用戶事件中觸發(fā),而不是進(jìn)入頁(yè)面后直接觸發(fā)
-
app links (android app links官方文檔)
- HTTPS的域名
- 跳轉(zhuǎn)后的落地頁(yè)是否是下載頁(yè)面
- assetlinks.json 配置在 host的.well-known下
- 官方生成/檢測(cè): android app links檢測(cè)
-
facebook (facebook app link官方文檔)
- 將需要的meta頭信息填充完畢
- 檢測(cè)鏈接 分享調(diào)試器 - Facebook for Developers , 確認(rèn)分享鏈接中獲取到了所需要的meta頭
- 分享過(guò)的鏈接會(huì)有緩存,在檢測(cè)中清楚緩存
- 如果web和wap鏈接一致,確認(rèn)在web中也添加了相同的meta頭,facebook會(huì)默認(rèn)從web中獲取
-
twitter (Twitter app card官方文檔)
- 將需要的meta頭信息填充完畢
- 檢測(cè)鏈接 Twitter app card 檢測(cè)
- 如果web和wap鏈接一致,確認(rèn)在web中也添加了相同的meta頭,facebook會(huì)默認(rèn)從web中獲取
鏈接
- webview如何屏蔽universal Link
- apple-app-site-association 官方文檔
- apple-app-site-association 檢測(cè)
- android app links官方文檔
- android app links檢測(cè)
- facebook app link官方文檔
- 分享調(diào)試器 - Facebook for Developers
- Twitter app card官方文檔
- Twitter app card 檢測(cè)
之前寫的文章大家感興趣的話,也可以閱讀了解討論:
HTTP協(xié)議淺談
Javascript作用域和閉包
Performance — 帶你監(jiān)控前端性能
