web 調起 App? 光知道 scheme 可不夠!

Gladyu發表於2018-04-08

很多人會遇到這個問題,大多數都是站在移動端的角度去解釋這個問題,本篇文章將會從web端的角度分析問題,解決問題

背景

瞭解背景,有助於我們更加深入的理解需求,分析需求

使用者和流量的量級決定了一款網際網路產品的優秀度。對一款優雅的網際網路產品而言,app端和web端是必不可少的,我們藉助它們形成閉環,保證使用者體驗和活躍度。除了端的覆蓋,我們還要做到端到端的互動,由此我們提出了產品的需求: wap頁喚起app,如果使用者沒裝app則跳轉到下載頁(引導頁都行)。如果使用者已安裝,根據URL跳到app內指定的介面,這也正是本文正要解決的問題

1. 先說一個最常規的方法,也是最常用的方法:scheme

舉個?:

wzry://videolists.show/mark/penta_kill?num=1
複製程式碼

這種方式需要事先在app中註冊相應的scheme,通過網頁訪問已註冊的scheme,達到調起App客戶端及相關介面

Android的相關配置: AndroidManifest.xml
<activity android:name=".ui.SchameFilterActivity">
	<intent-filter>
	<action android:name="android.intent.action.VIEW" />
	<category android:name="android.intent.category.DEFAULT" />
	<category android:name="android.intent.category.BROWSABLE" />
	<data
	    android:host="videolists.show"
	    android:path="/mark/penta_kill"
	    android:scheme="wzry"/>
	</intent-filter>
</activity>
複製程式碼
iOS 影象化配置還說啥

web 調起 App? 光知道 scheme 可不夠!

至於定義scheme以後的邏輯請自行google,但是邏輯中一定要做防護

好了我們可以愉快的使用了

<a href="wzry://videolists.show//mark/penta_kill?vid=666">你過來啊!</a>
複製程式碼

(你也用直接訪問地址的方式,這種方式有小坑:有些瀏覽器是會返回404狀態碼,或者變成搜尋結果頁,小煩)

宣告sheme後,回過頭來看一下需求:使用者安裝了app,調起app。使用者未安裝我們需要引導使用者下載 。那這裡就有一個問題了:網頁是不知道使用者有沒有安裝app的。那我們換一個思路----可不可以知道頁面被置於後臺了?頁面進入後臺,可以認為是喚起成功了;頁面沒進入後臺,說明喚起失敗(沒安裝or其他原因)

一個新的API完全滿足上邊提到的需求 : Page Visibility API,文件中詳細的介紹了這個API---->可以準確的知道頁面當前的狀態(前臺,後臺等狀態),但是這個API太新了,需要較新的瀏覽器支援,覆蓋率有點低。放一張圖感受一下:

web 調起 App? 光知道 scheme 可不夠!
所以我們不能大面積使用。如之奈何?交給黑科技了: 定時器

我先說一下思路:

  • setTimeout的實現過程:

    瀏覽器嘗試開啟URL scheme並記錄時間點t1,在2秒計時後,檢查當前時間t2,如果t2-t1 > 2200ms,說明喚起app成功(喚起app會是瀏覽器的定時器延後執行),如果t2-t1 < 2200ms,可能沒有安裝app,可以引導使用者進入下載頁

  • setInterval實現過程

    原理上跟setTimeout相似,方法上換成設定一個比較小的時間間隔(例如20ms),執行多次(例如100),比較執行完100次的總耗時與20*100的時間差。邏輯判斷同setTimeout

優缺點:

  • setTimeout不穩定,因為Android是基於Linux分時多工的,setTimeout的基準偏差不會那麼大,比較難調教

  • setInterval要好一點,頁面一直處於前臺(調起app失敗),則100次跑完,總耗時與 100x20=2000ms不會有太大差異,但頁面在後臺執行時(調起app成功),此時間會明顯超過2000ms

注:不知道setTimeout,setInterval為什麼會延遲執行的,請惡補一波它們的執行原理

好了嘴炮打完,上?:

setTimeout

var openTime = +new Date();
window.location.href = 'wzry://videolists.show/mark/penta_kill?num=1'
var timer = setTimeout(function () {
    if ((new Date()) - openTime < 2200) {//加了200ms基準誤差
        window.location.href = 'you app download page';
    }
    if ((new Date()) - openTime > 2200) {
        clearTimeout(timer);
    }
}, 2000);
複製程式碼

setInterval

var limit_num = 100;
var openTime = +new Date();
window.location.href = 'wzry://videolists.show/mark/penta_kill?num=1'
var timer = setInterval(function () {
   if(limit_num > 0){
        limit_num--;
   }else{
        if ((new Date()) - openTime < 2200) {//加了200ms基準誤差
            window.location.href = 'you app download page';
        }
        clearTimeout(timer);
   }
}, 20);
複製程式碼

當我們完成這些操作之後,在一般環境下是可以正常喚起app的了

2. 那我再說一下特殊情況 ----微博,微信等

像這種爸爸級別的應用是有scheme白名單的,只有白名單內的scheme才不會被過濾掉,就問你怕不怕?嗯?

像這種我們怎麼去解決那?

(I). 其實最簡單的辦法就是像爸爸低頭----使用應用寶。

使用它頒發給你的應用地址,向這個地址跳轉,然後一切就交給爸爸了,直接無視微信什麼的,直接帶你飛到app內

(II). 使用 Universal Links

它是iOS9推出的一項強大的功能。可以讓你 通過http連結的方式喚起你的app(不管你的在微信/微博還是其他app內,因為Universal Links是由系統直接處理的),下面我來簡單說一下怎麼使用Universal Links完成喚醒的app,你也可以通過官方文件詳細的瞭解它。

首先

  • 必須給域名配置https才能使用它
  • 在開發者中心做配置:找到對應的App ID ——> Associated Domains,設定成Enabled
  • 開啟工程,在capabilities中設定Associated Domains,在其中的Domains中填入你想支援的域名,注意必須以applinks:為字首
  • 編輯apple-app-site-association檔案(檔名,json格式不能改變,注意apple-app-site-association檔案是沒有格式字尾的)
{
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID": "TeamID + BundleId TeamID",
                "paths": [ "/mark/penta_kill?num="]
            }
        ]
    }
}
複製程式碼
  • 上傳該檔案到域名的根目錄,確保可以被訪問

做完這些,你就可以嘗試喚起你的iOS app了

這裡還要強調一下 攔截的地址 一定要與當前webview的url 不在同一個域名下。這樣Universal Links才會生效,不要問我怎麼知道的,都是血淚啊

3. 還有最後一種 ---- 自己做引導,引導使用者瀏覽器開啟,繞過限制。不過這樣,步驟較多,折損率可能會升高

綜上,Android app除了使用應用寶跳轉喚起和引導頁沒發現其他更好的辦法,iOS方案多了個Universal Links,這也是為什麼我們經常看到有些app在微信/微博中 iOS端可以直接喚起app,而Android端經常是需要走一道應用寶的原因

好了,以上內容就是我對喚起app的一些總結和經驗,希望可以幫助到你

未經本人允許,不得轉載。文章有疏漏淺薄之處,請各位大神斧正

修改 : 經過驗證微信新增了一個遮蔽Universal Links的爆炸功能,大致原理參考:Prevent universal links from opening in WKWebView/UIWebView

微信內建瀏覽器想怎麼改就怎麼改,厲害厲害

相關文章