如何喚醒APP吟秩?

移動(dòng)互聯(lián)網(wǎng)時(shí)代,“用戶增長”成為每個(gè)公司關(guān)注的重點(diǎn)話題驶社。為了將更多用戶引導(dǎo)到客戶端內(nèi)企量,產(chǎn)品經(jīng)理會(huì)習(xí)慣性地在網(wǎng)頁的各個(gè)地方巧妙隱藏喚醒App的“機(jī)關(guān)”。

常見的出現(xiàn)場景

瀏覽器 —喚醒—> App
??用戶在瀏覽器中瀏覽網(wǎng)頁時(shí)亡电,當(dāng)檢測到該網(wǎng)頁來自于某個(gè)App時(shí)届巩,此時(shí)可以引導(dǎo)用戶呼起或者下載App
微信、QQ —喚醒—> App
??用戶將App中自己喜歡的內(nèi)容分享到微信份乒、QQ恕汇,在站外打開網(wǎng)頁時(shí)腕唧,可以正常瀏覽,也可以引導(dǎo)用戶呼起或者下載App

接下來瘾英,讓我們深入研究下喚醒App的幾種解決方案枣接?

喚醒App的幾種解決方案

1、 URL Scheme 方式

  • 條件
    • APP需要注冊自己的URL Scheme方咆,用來唯一標(biāo)識(shí)一個(gè)App月腋。
    • Scheme格式:<scheme域名>://<path>?<params>=<value>
  • 代碼

1) iframe方式

var _iframe = document.createElement('iframe');
_iframe.src = scheme;
_iframe.style.display = 'none';
 document.body.appendChild(_iframe);
 window.setTimeout(function(){
    document.body.removeChild(_iframe);
    if((+new Date()) - openTime > 2500) {
        window.location.href = url;
   }
}, 2000);

2)a鏈接方式
<a href="<scheme域名>://<path>?<params>=<value>">打開APP</a>
3)location.href 直接跳轉(zhuǎn)
window.location.href = "<scheme域名>://<path>?<params>=<value>"

  • 優(yōu)缺點(diǎn)

    • 優(yōu)點(diǎn):iOS、Android均支持瓣赂,開發(fā)簡單榆骚;web-native協(xié)議制定簡單。
    • 缺點(diǎn):

    由于要考慮用戶沒有安裝App的情況煌集,所以當(dāng)用戶沒有安裝時(shí)妓肢,通過延遲會(huì)跳轉(zhuǎn)到AppStore。iOS9+當(dāng)跳轉(zhuǎn)App時(shí)苫纤,會(huì)彈出一個(gè)彈框碉钠,讓用戶選擇是否跳轉(zhuǎn),此時(shí)還在當(dāng)前頁卷拘,setTimeout中的代碼會(huì)繼續(xù)執(zhí)行喊废,導(dǎo)致用戶還沒來得及選擇,就已經(jīng)跳到AppStore栗弟。
    若用戶未安裝App污筷,Android上scheme打開失敗,沒有任何提示乍赫,延遲之后瓣蛀,跳下載頁。但是iOS9+會(huì)先彈出個(gè)萬惡的跳轉(zhuǎn)失敗的彈窗雷厂,延遲之后惋增,再跳下載頁。

    iOS9+呼端確認(rèn)彈窗

image.png

iOS9+萬惡的跳轉(zhuǎn)失敗的彈窗

image.png
  • 支持情況

    URL Scheme方式一直被廣泛使用改鲫,但是有些App并不認(rèn)可诈皿,比如:微信、手機(jī)百度像棘;站在這些App的角度上考慮纫塌,他們并不希望用戶為了看更多分享內(nèi)容,跳出自己的App讲弄,因此他們就在客戶端內(nèi)攔截了scheme方式呼端,導(dǎo)致URL Scheme方式在微信依痊、手機(jī)百度中徹底失效1艹T跖!當(dāng)然微信是存在一個(gè)白名單的瓶摆,對于白名單中的分享鏈接是不會(huì)屏蔽scheme調(diào)用的凉逛。
    安卓App廠商差異很大,情況比較多樣化(比如:Android Chrome版本25+通過iframe方式呼端失敗 )

  • 兼容性

Android系統(tǒng):Chrome for Android無法通過iframe方式來調(diào)用scheme群井,而通過a鏈接的方式可以成功調(diào)用状飞,而針對Chrome內(nèi)核的瀏覽器如360瀏覽器,對于iframe和a鏈接的方式都能支持书斜,所以對Chrome內(nèi)核的瀏覽器采用a鏈接的方式來調(diào)用scheme诬辈;對于其他瀏覽器,如UC荐吉,QQ瀏覽器則采用iframe方式調(diào)用scheme焙糟。
iOS系統(tǒng):Safari瀏覽器不支持 iframe可直接做頁面跳轉(zhuǎn);對于UC样屠、Chrome穿撮、QQ只能通過a鏈接方式調(diào)用scheme。
上述提到的屏蔽scheme方式的App:呼端失敗跳下載頁痪欲。

2、 Android Intent 方式

  • 條件

    A little known feature in Android lets you launch apps directly from a web page via an Android Intent. One scenario is launching an app when the user lands on a page, which you can achieve by embedding an iframe in the page with a custom URI-scheme set as the src, as follows: <iframe src="paulsawesomeapp://page1"> </iframe>. This works in the Chrome for Android browser, version 18 and earlier. It also works in the Android browser, of course.

  • 構(gòu)造intent字符串
intent:
HOST/URI-path
#Intent; 
  package=[string];                 //  android app包名
  action=[string];      
  category=[string];    
  component=[string];               
  scheme=xxxx;                  // 協(xié)議頭
  S.browser_fallback_url=[url]          // 可選业踢,scheme啟動(dòng)客戶端失敗時(shí)的跳轉(zhuǎn)頁栗柒,一般為下載頁,需編碼
end; 
  • 代碼
<!--Intent方式呼端-->
<a href="intent://<role>/<path>#Intent;scheme=<scheme>;package=com.domain;S.browser_fallback_url=[url];end">打開APP</a>
  • 支持情況
    • iOS:不支持
    • Android:Android的Intent方式比URL Scheme方式要靠譜陨亡,能通過參數(shù)設(shè)置呼端失敗要跳轉(zhuǎn)的地址傍衡;若手機(jī)能匹配到對應(yīng)App,則成功呼到對應(yīng)頁面负蠕,若未安裝蛙埂,會(huì)跳手機(jī)自帶的應(yīng)用市場下載。
  • 參考文檔
    Android Intents with Chrome

3遮糖、Universal Links

  • 條件

    • iOS9+系統(tǒng)
    • Universal Link是通過標(biāo)準(zhǔn)的http/https協(xié)議鏈接喚起App绣的;若未安裝App,訪問此通用鏈接欲账,可以自定義頁面屡江;
  • 優(yōu)缺點(diǎn)

    • 優(yōu)點(diǎn)

      唯一性:不像自定義的Scheme方式,該方式是通過標(biāo)準(zhǔn)的http/https協(xié)議的鏈接到你的App.未安裝App時(shí)赛不,自定義的Scheme方式無法打開惩嘉,而http/https的Universal Link通用鏈接有很好的兼容性;
      安全性:當(dāng)用戶安裝了App時(shí)踢故,iOS會(huì)從網(wǎng)站上去下載說明文件(下面所說的apple-app-site-association的文件文黎,說明這個(gè)App可以打開哪些http鏈接),這個(gè)說明文件是只有開發(fā)者有權(quán)限寫并上傳到網(wǎng)站的根目錄惹苗,所以App與網(wǎng)頁http鏈接的關(guān)聯(lián)是安全的。
      可變性:當(dāng)用戶沒有安裝App時(shí)耸峭,Universal Link鏈接也能正常打開桩蓉,也可以設(shè)置:未安裝App時(shí),可以用Safari打開該鏈接劳闹。
      簡單性:一個(gè)URL鏈接院究,可以將網(wǎng)站和App做關(guān)聯(lián)。
      私有性:其他App在不知道你是否安裝的情況下本涕,也可以和你的App進(jìn)行相互通信(因?yàn)橹皇且粋€(gè)普通的http鏈接耙堤)。

    • 缺點(diǎn):只支持 iOS9+系統(tǒng)偏友;在開啟了Universal Link之后蔬胯,用戶可以通過該方式呼端,成功呼端后右上角會(huì)顯示鏈接地址(iOS9位他、 iOS10會(huì)出現(xiàn)面包屑導(dǎo)航氛濒,iOS11+沒有面包屑導(dǎo)航(如下圖)),當(dāng)用戶一不小心手動(dòng)點(diǎn)擊這個(gè)地址時(shí)(俗稱:Universal link誤關(guān))鹅髓,Universal Link會(huì)失效(失效后舞竿,Universal Link呼端就永遠(yuǎn)失敗了,永遠(yuǎn)呼不起來窿冯,跳下載頁骗奖,所以我們要重新激活Universal Link)需要引導(dǎo)用戶到Safari瀏覽器,引導(dǎo)用戶點(diǎn)擊Safari內(nèi)置頂部的系統(tǒng)呼端條醒串,重新激活Universal Link执桌,也可以將鏈接復(fù)制到備忘錄中,長按鏈接出現(xiàn)用App打開芜赌,也可激活Universal Link仰挣。


      image.png

      image.png

      image.png

      image.png
  • 開啟Universal Links開關(guān)

    • 注冊一個(gè)域名并支持https
    • 有權(quán)限上傳到網(wǎng)站根目錄.well-know(這個(gè)權(quán)限是為了上傳一個(gè)Apple指定的文件apple-app-site-association)
    • 創(chuàng)建一個(gè)JSON文件名字為apple-app-site-association的文件(文件名必須是這個(gè)!2颉1旌)
// apple-app-site-association文件配置
{
    "applinks": {
        "apps": [],
        "details": {
            "ZVC23L5QY4.com.domain.app": {
                "paths": ["*"]
             }
        }
     }
  }

注意:
大小寫敏感;嚴(yán)格匹配配置的path路徑洲愤;apple-app-site-association文件的讀取颓芭,只在第一次啟動(dòng)App時(shí)加載;iOS9.2開始柬赐,在相同的domain下亡问,Universal Link不work,必須跨域肛宋;
以上只是重點(diǎn)部分內(nèi)容玛界,詳細(xì)說明請參考:
打通 iOS 9 的通用鏈接(Universal Links)

了解了呼端的幾種方式万矾,分享下我們團(tuán)隊(duì)完整的呼端解決方案

完整的解決方案

由于我們無法判斷用戶是否安裝App,所以以上所有的方案都只能嘗試呼端慎框。整合上述這些方案,具體思路如下:

// iOS9+在開啟Universal Link開關(guān)的前提下后添,優(yōu)先使用Universal Links方式呼端
if (!closeUnilink && isios && iosVer && iosVer >= 9) {
      // 通過Universal Links方式獲取通用呼端鏈接
      const unilink = getUnilink(opts.scheme, opts.unilink);
      if (unilink) {
        window.location.href = unilink;
      }
    } else {
  // 不支持Intent方式笨枯,采用 URL Scheme 方式
   if (!canIntent) {
       // iOS9+ Safari 不支持iframe方式
       if (!isWv && (ua.indexOf('safari') > -1 && iosVer && iosVer >= 9)) {
          link(scheme);
        } else {
          iframe(scheme);
        }
        // 處理未安裝客戶端情況:延遲跳轉(zhuǎn)到下載頁
        setTimeout(function () {
              gotoDownload();
            },延長時(shí)間);

    } else {
       // Android支持Intent方式時(shí): intent呼起客戶端
      intent(scheme);
  }
}

注意:
??前面提到的URL Scheme 方式的iframe和a鏈接方式,需要考慮用戶未安裝客戶端情況:延遲跳轉(zhuǎn)到下載頁遇西。這個(gè)延長時(shí)間的設(shè)置很關(guān)鍵O诰!粱檀!延長時(shí)間的設(shè)定需要考慮:如果延長時(shí)間小于App的啟動(dòng)時(shí)間洲敢,App還未啟動(dòng),就執(zhí)行setTimeout代碼茄蚯;如果延長時(shí)間較長压彭,當(dāng)用戶未安裝App時(shí),需要等待特別久的時(shí)間才能執(zhí)行setTimeout代碼渗常。
??對代碼封裝壮不,根據(jù)不同業(yè)務(wù)呼端需求,可以提煉幾個(gè)可配參數(shù):呼端scheme地址皱碘、呼端失敗是否跳下載頁询一、下載頁鏈接、呼起客戶端失敗超時(shí)時(shí)間癌椿、呼起回調(diào)健蕊;這樣做的好處是:調(diào)用組件時(shí),根據(jù)不同需求傳遞參數(shù)即可踢俄。

優(yōu)化

  • 實(shí)際測試時(shí)發(fā)現(xiàn):當(dāng)成功呼起App時(shí)缩功,用戶再次返回到Safari瀏覽器的頁面時(shí)已經(jīng)跳轉(zhuǎn)到下載頁面了,此時(shí)需要對setTimeout做清除定時(shí)器處理褪贵。
  • 當(dāng)本地App被喚起時(shí)掂之,App處于設(shè)備可視窗口的最高層,此時(shí)瀏覽器進(jìn)入后臺(tái)程序頁面會(huì)被隱藏掉脆丁,會(huì)觸發(fā)pagehide與visibilitychange事件世舰,此時(shí)應(yīng)先清除setTimeout事件;同時(shí)槽卫,document.hide屬性設(shè)置為true跟压,所以setTimeout內(nèi)不做跳轉(zhuǎn)處理,防止頁面跳轉(zhuǎn)到下載頁面歼培。
  • 實(shí)際開發(fā)中震蒋,為了防止某些瀏覽器不支持這個(gè) Page Visibility API茸塞,最好同時(shí)監(jiān)聽pagehide事件,這樣會(huì)比較保險(xiǎn)(相關(guān)代碼如下)查剖。
// 頁面隱藏時(shí)觸發(fā)
window.onpagehide = function () {
   if (timeout) {
    clearTimeout(timeout);
   }
 };
// 頁面的可見狀態(tài)變化時(shí)钾虐,會(huì)觸發(fā)
 visibilitychange = function () {
    const tag = document.hidden || document.webkitHidden;
    if (tag && timeout) {
      clearTimeout(timeout);
    }
  }
document.addEventListener('visibilitychange', visibilitychange, false);
// 兼容多的瀏覽器事件
document.addEventListener('webkitvisibilitychange', visibilitychange, false);

代碼中有關(guān)事件具體參考:Page Visibility API文檔

測試結(jié)果

測試機(jī)型主要針對iOS和Android默認(rèn)瀏覽器、Chrome等一些常用主流瀏覽器笋庄,iOS9+微信內(nèi)嵌請嘗試使用 Universal Link 方式呼起客戶端效扫。

demo頁面

測試反饋

image.png


以上完整的呼端解決方案我們完美的使用了很久,直到2018年1月7日直砂,微信封掉了內(nèi)置瀏覽器里的Universal Link呼端菌仁,導(dǎo)致微信內(nèi)引導(dǎo)呼端的流程徹底中斷!>苍荨济丘!

考慮到微信是站外分享很重要的渠道,我們當(dāng)然不能G⒅D∶浴!放過H枋俊@嵯啤!

  • 首先:我們有一個(gè)思路:既然微信容器內(nèi)不能使用Universal Link呼端颂碘,那么我們可以脫離微信容器异赫,做一個(gè)中轉(zhuǎn)頁面,引導(dǎo)用戶去瀏覽器呼端头岔。
  • 其次:想想用戶之前習(xí)慣性操作都是一次性直接點(diǎn)擊呼端成功的塔拳,引導(dǎo)的話鏈路有點(diǎn)長,用戶難免會(huì)吐槽峡竣。
    所以靠抑,針對中轉(zhuǎn)頁面iOS客戶端新增 Universal Link 匹配規(guī)則(以中轉(zhuǎn)頁面鏈接為主),以便在微信內(nèi)适掰,「使用瀏覽器打開」后颂碧,被系統(tǒng)攔截后可以直接打開客戶端,不用引導(dǎo)去瀏覽器类浪。
    當(dāng)然载城,對于Android用戶,我們考慮到也可以引導(dǎo)用戶去應(yīng)用寶呼端费就。
  • 最后做了一點(diǎn)小優(yōu)化:在瀏覽器的中轉(zhuǎn)頁面中诉瓦,采用雙保險(xiǎn)呼端。當(dāng)客戶端配置好Universal Link鏈接時(shí),Safari瀏覽器訪問中轉(zhuǎn)頁面睬澡,頁面頂部會(huì)出現(xiàn)系統(tǒng)的呼端條固额,引導(dǎo)用戶下拉,用戶可以選擇使用系統(tǒng)呼端條打開煞聪,從而也能激活Universal Link斗躏,防止誤關(guān);采用按鈕點(diǎn)擊嘗試呼端(關(guān)閉Universal Link方式)米绕。
  • 針對Universal Link誤關(guān)的現(xiàn)象瑟捣,可以采納這兩種方法
    • 用樣式的方式遮擋右上角面包屑導(dǎo)航≌じ桑可以使得iOS9、iOS10和iOS11+達(dá)到視覺的一致性捐祠。但是樣式控制不好碱鳞,用戶體驗(yàn)會(huì)很不好。
    • 獲取面包屑導(dǎo)航的觸發(fā)事件踱蛀,可以手動(dòng)的控制觸發(fā)后跳轉(zhuǎn)的地址(可以引導(dǎo)跳轉(zhuǎn)到中轉(zhuǎn)頁面窿给,引導(dǎo)用別的方式呼端)。這種算hack的解決方案率拒。要考慮成本問題崩泡,是否采納。

中轉(zhuǎn)頁面

image.png

iOS客戶端采用Universal link進(jìn)行系統(tǒng)攔截

image.png

雙保險(xiǎn)呼端

image.png

image.png

至此猬膨,站外呼端方案完美落幕~~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末角撞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子勃痴,更是在濱河造成了極大的恐慌谒所,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沛申,死亡現(xiàn)場離奇詭異劣领,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)铁材,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門尖淘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人著觉,你說我怎么就攤上這事村生。” “怎么了固惯?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵梆造,是天一觀的道長。 經(jīng)常有香客問我,道長镇辉,這世上最難降的妖魔是什么屡穗? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮忽肛,結(jié)果婚禮上村砂,老公的妹妹穿的比我還像新娘。我一直安慰自己屹逛,他們只是感情好础废,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著罕模,像睡著了一般评腺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上淑掌,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天蒿讥,我揣著相機(jī)與錄音,去河邊找鬼抛腕。 笑死芋绸,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的担敌。 我是一名探鬼主播摔敛,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼全封!你這毒婦竟也來了马昙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤售貌,失蹤者是張志新(化名)和其女友劉穎给猾,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體颂跨,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡敢伸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了恒削。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片池颈。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖钓丰,靈堂內(nèi)的尸體忽然破棺而出躯砰,到底是詐尸還是另有隱情,我是刑警寧澤携丁,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布琢歇,位于F島的核電站兰怠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏李茫。R本人自食惡果不足惜立轧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一淤刃、第九天 我趴在偏房一處隱蔽的房頂上張望暂氯。 院中可真熱鬧台盯,春花似錦、人聲如沸宠互。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽予跌。三九已至搏色,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間券册,已是汗流浹背继榆。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留汁掠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓集币,卻偏偏與公主長得像考阱,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子鞠苟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 引言 最近在做客戶端開發(fā)的工作中乞榨,需要解決一些渠道流量監(jiān)控的問題。發(fā)現(xiàn)在喚醒a(bǔ)pp的時(shí)候涉及到很多這樣那樣的lin...
    Edie小哪吒閱讀 23,716評論 15 45
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,509評論 25 707
  • 需求 點(diǎn)擊免費(fèi)下載按鈕,如果本機(jī)安裝了此應(yīng)用跨细,那么就喚醒該應(yīng)用鹦倚,如果沒有安裝此應(yīng)用,那么就跳轉(zhuǎn)下載鏈接冀惭。 其實(shí)H5...
    聰明的湯姆閱讀 6,114評論 2 14
  • 移動(dòng)互聯(lián)時(shí)代震叙,很多互聯(lián)網(wǎng)服務(wù)都會(huì)同時(shí)具備網(wǎng)站以及移動(dòng)客戶端,很多人認(rèn)為APP的能幫助建立更穩(wěn)固的用戶關(guān)系散休,于是經(jīng)常...
    zyl04401閱讀 43,905評論 17 72
  • 愛情和婚姻都一樣,不能失去了自我,失去了自我夺颤,你也就失去了他們痢缎。 今天看了一個(gè)視頻,講的是一個(gè)女孩不顧家庭的反對拂共,...
    嫻來吳侍閱讀 374評論 0 0