H5打開APP技術總結

  在H5頁面打開APP的方法一般有兩種,在IOS 9以前,一般使用的技術是URL Scheme。這種方式雖然可自定義程度很高,能夠巧妙地實現很多跳轉,但弊端也很明顯:我們只能通過 scheme://example 這種格式的鏈接來實現跳轉,而且現在蘋果還對這種方式的跳轉加了一個提示框:“是否打開XXX”。對於對Web和原生App交互的場景需求量很大的產品來說,這樣的跳轉方式顯然是步驟冗雜的,用戶體驗並不好。
  iOS 9 以後,Universal Links 的出現完美的解決了這個問題。它所提供的直接、順暢、無縫銜接的跳轉能夠讓用戶體驗提升一個很大的級別。用戶可以點擊開發者指定的類似於 https://example.com/t 的URL直接喚醒App,而不需要在瀏覽器打開再點擊其他按鈕,實現真上的一鍵直達,無縫鏈接。
  但是Universal Links只能在IOS 9+的平臺纔可以使用,我們還需要兼容微信、安卓和IOS 9以前的版本,所以項目中,我們會採用URL Scheme和Universal Links兩個結合的方式。

1.技術介紹

1.1 URL Scheme

  項目中需要配置 URL Scheme 以用於場景恢復時跳轉到應用中(這裏的scheme要唯一確定,不要與其他應用一致,建議使用項目名稱作爲scheme,不然有可能會跳轉到其他的應用裏)。
  在iOS工程中選擇工程 Target,選擇 Info 選項,然後打開 URL Types,添加 URL Scheme。可以自定義協議名稱,如moblink。這個形式的 URI 就會關聯跳轉到工程中。
  配置好後安裝APP後,直接在訪問設置好的 URL Scheme可以直接打開APP,如平時我們用的比較多的APP,默認的 URL Scheme如下:

  • QQ: mqq://
  • 微信: weixin://
  • 騰訊微博: TencentWeibo://
  • 淘寶: taobao://
  • 支付寶: alipay://
  • 微博: sinaweibo://

      使用方式: <a href="weixin://">打開微信</a> 點擊a標籤就可以打開了微信(如果安裝了微信)。
      這種方式訪問是比較簡單的,安卓和IOS都可以使用,但是在微信端就不行了,微信端設置了白名單,完全屏蔽了URL Scheme 用法,除非加入了白名單,像京東就可以直接打開,否則是不可能的,那我們還有下面的辦法來解決這個辦法。

  用URL Scheme 不能在微信裏打開APP,但是在IOS 9+的系統上還是有解決辦法的,那就是用Universal Links,官方網站https://developer.apple.com/library/content/documentation/General/Conceptual/AppSearch/UniversalLinks.html,這裏都是英文的,網上也有很多文章。開篇就說了,如果你單純爲了能讓H5打開App,Schema就能做到了,Universal Links的意義則是把普通url,也賦予了能打開App的能力,而不必編寫專門的Schema Url去喚起App,在沒裝App的時候,Universal Links他也是一個合法的url鏈接,瀏覽器可以正常跳轉,因此不會出現在iOS上討人厭的框。而且Universal Links目前還沒有基於iOS的UI/WKWebView的應用進行攔截,所以目前看還是能突破微信/手百的封鎖。(以後,不好說啊~)

2.DEMO示例(IOS篇)

2.1 IOS平臺配置

  • 在蘋果開發者賬號下,將本項目的Associated Domains 開關Enable;
  • 在工程中選擇好本項目的證書和描述文件;如果是已存在的項目,請完成步驟1後重新下載新的描述文件;
  • 在工程中打開Associated Domains開關,並設置域名

這裏寫圖片描述

測試一級域名:aa.tk 測試二級域名:sit.aa.tk

Domains域名 作用
applinks:aa.tk 服務器主域名
applinks:www.aa.tk
applinks:sit.aa.tk 服務器子域名,用於點擊自定義按鈕跳轉app,需要跨域才能生效

注:用於跳轉打開app的域名需要支持https,如果是一級域名頁面有個按鈕,點擊按鈕跳轉二級域名來打開app,那麼二級域名需要支持https。這裏DEMO的二級域名不支持https,所以採用的方案是二級域名跳轉到一級域名來打開APP。

相關代碼:

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{ 
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
        NSURL *webpageURL = userActivity.webpageURL;
        NSString *host = webpageURL.host;
        // 在這裏寫需要的邏輯,比如跳轉到某個詳情頁
        if ([host isEqualToString:@"www.aa.tk"]) {    
            NSString *url = [userActivity.webpageURL.description substringFromIndex:23];
            NSArray *mat = [url componentsSeparatedByString:@"/"];
            if (mat.count == 2) {
                NSString *type = [mat objectAtIndex:0];
                NSString *key = [mat objectAtIndex:1];
                if ([type isEqualToString:@"goods"]) {
                    [self openGoodsView:key];
                }
            }
        }
        else{
            [[UIApplication sharedApplication] openURL:webpageURL];
        }
    }
    return YES;
}

當通過Universal Link進入app時,會觸發此代理,可以從前端傳遞參數,這裏做相應處理,理論上可以跳轉到APP的任何一個頁面。

2.2 配置文件apple-app-association

  1. 配置文件的位置放在跳轉域名的根目錄,DEMO將一級域名設置爲打開APP的地址,所以上傳到主域名對應服務器的根目錄。判斷位置是否正確可以訪問”https://www.aa.tk/apple-app-site-association“查看,如果正確顯示則正確。
  2. 配置文件的內容如下:

    {
        "applinks": {
            "apps": [],
            "details": [{
                "appID": "xxx",
                "paths": ["/testlinkapp/*"]
            }]
        }
    }

      “appID”是團隊ID的值或應用程序ID前綴,緊隨其後的是boundle ID。(appID key 就是在你的應用程序的“application-identifier”),蘋果開發者賬號》merbership下查看teamid,bundle id 爲項目自己定義的唯一標識。
      “paths”是一個字符串數組,指定你的網站的哪些部分支持跳轉到應用程序和哪些網站的部分不想跳轉到應用。指定一個域名,不應該作爲一個通用的鏈接處理,在域名paths字符路徑的前部添加“NOT”(包括空間T)。
      這裏設置了”/testlinkapp/*”,也就是說訪問”/testlinkapp/”文件夾下任何文件(不管是否存在)都可以,例如”https://www.aa.tk/testlinkapp/xxx“。如果沒有跨域,就不能跳轉,不過下滑可以顯示橫幅,點擊打開也可以打開。

2.3 下載安裝APP並測試

  如果配置文件發生更改,則需要重新下載APP。這裏一級域名和二級域名對應的是同一個文件根目錄。
  測試案例:

環境 訪問url 點擊跳轉url 是否跨域 結果
瀏覽器 https://www.aa.tk/testlinkapp/xxx 頁面不存在,下滑出現”打開APP“橫幅,點擊打開會打開APP
瀏覽器 http://sit.aa.tk/testlinkapp2/demo.html https://www.aa.tk/testlinkapp/zzz 點擊demo頁的按鈕,直接打開了APP
瀏覽器 https://www.aa.tk/testlinkapp/xxx 直接打開APP
瀏覽器 http://sit.aa.tk/testlinkapp2/demo.html https://www.aa.tk/testlinkapp/zzz 點擊demo頁的按鈕,直接打開了APP

2.4 沒有安裝跳轉到APP Store

  使用Universal Links時將跳轉的頁面設置爲下載頁面,如果APP已經安裝就直接打開APP,如果沒有安裝則進入下載頁面。
  使用URL Scheme時用延時,超過三秒沒有打開APP,則打開下載頁面,具體實現後面源碼部分。

3.DEMO示例(AOS篇)

安卓不能採用Universal Links的方法,這裏使用的是URL Scheme+intent

3.1 安卓配置文件

 var AppConfig = {
    "scheme": "xxx",
    "package": "com.xxx",
    "action": "android.intent.action.VIEW",
    "category": "android.intent.category.BROWSABLE",
    "host":"www.xxx.com",
    "FAILBACK_ANDROID":"https://www.xxx.com/xxxx",
    "FAILBACK_IOS":"itms://itunes.apple.com/hk/app/bochk/xxx?mt=8"
 };

  這裏的參數由安卓同事提供,“FAILBACK_ANDROID”是AOS沒有打開app跳轉到下載頁面的鏈接
“FAILBACK_IOS”是IOS沒有打開app跳轉的下載鏈接,這兩個是前端配置的。
  在Chrome瀏覽器中使用intent方法,在非Chrome瀏覽器使用URL Scheme,Chrome中使用intent的好處:Chrome可以識別S.browser_fallback_url參數,如果沒有安裝app,則直接跳轉,而不用我們自己判斷是否安裝app,在非Chrome中通過延時判斷是否安裝app會有弊端:(用schema方法實現)點擊打開app,會有提示“是否用XXX應用打開”的提示框,如果用戶沒有點擊按鈕超過設置的時間,頁面就直接跳轉了下載頁,體驗不好。具體實現看源碼。

3.2 安卓端在微信端暫時沒有辦法,只能跳轉應用寶或者下載頁面。

4.Universal Links坑及建議

4.1 配置apple-app-association

  • 域名必須支持https
  • 域名根目錄下放這個文件apple-app-association,不帶任何後綴
  • 文件爲json格式保存爲文本即可
  • json按着官網的要求填寫即可

      測試是否正確,直接訪問域名+配置文件名如果能正確訪問則放置的位置是正確的。例如你想通過訪問”https://aa.test.com/xxx“來打開app,那麼你要把配置文件放在”https://aa.test.com/“對應服務器根目錄,通過訪問”https://aa.test.com/apple-app-association“能直接訪問配置文件則是正確的。

4.2 配置Domains

  • 開發者中心證書打開Associated Domains
  • 工程配置Associated Domains
  • 將你apple-app-association所在域名配置進去
  • 給你的工程像Schema的OpenUrl一樣,編寫App被喚醒後的處理邏輯
      在配置Domains時,我們需要將一級域名和二級域名都要添加進去,這樣做是爲了通過自定義按鈕打開app,而這種做法需要跨域,所以需要配置兩個,如果用二級域名來打開app,則二級域名也需要支持https。

4.3 Universal Links基本運作流程

  1. APP第一次啓動 or APP更新版本後第一次啓動
  2. APP向工程裏配置的域名發起Get請求拉取apple-app-association Json File
  3. APP將apple-app-association註冊給系統
  4. 由任意webview發起跳轉的url,如果匹配了apple-app-association註冊過的通用鏈接(path字段配置)
  5. 打開App,觸發Universal Link delegate
  6. 沒匹配,webview繼續跳轉url(當普通的url跳轉)

4.4 跨域

Universal Links必須要求跨域,如果不跨域,就不能實現自定義按鈕打開APP,經測試如果不跨域,直接輸入配置的url,會跳轉到url,下滑會出現如下的橫幅,點擊打開也可以打開app。
這裏寫圖片描述

  這裏我們用跨域主要是用於自定義按鈕打開App,如果打開一個頁面”http://www.aa.com/index.html“,這個頁面裏面有個”打開APP“的按鈕,點擊按鈕去打開APP。我們用Universal Links技術就是點擊按鈕讓頁面跳轉到我們在apple-app-association配置文件裏配置好的路徑裏去,不管訪問的文件是否存在,都能打開APP。例如我們設置的Universal Links的域名爲二級域名”https://bb.aa.com/“,配置文件的path爲”/demo/*”,我們將按鈕的跳轉鏈接設置爲”https://bb.aa.com/demo/xxx“,這時就可以打開APP。

PS:
1.這裏配置文件就要放在二級域名的根目錄
2.xxx可以不存在,也可以存在
3.如果沒有跨域的話,會當普通的url跳轉
4.二級域名同樣要添加到Domain裏
5.跨域最好使用二級域名的方式

4.5 Universal Links會因爲用戶的行爲而失效

  Universal LInks觸發後打開APP,這時候APP的狀態欄右上角會有文字提示來自XXX App,可以點擊狀態欄的文字快速返回原來的APP,如果用戶點擊了返回微信,就會被iphone記住,認爲用戶不需要跳出原APP打開新APP,因此這個APP的Universal Links會被關閉,再也無效。還有在備忘錄里長按Universal Links鏈接會出現”用XXApp打開”的選項,如果你點擊了”用Safari瀏覽器打開”,那麼點擊此鏈接也會默認用瀏覽器打開url,而不是打開APP。
  想要開啓也不是不行,讓用戶重新用safari打開,Universals Links的頁面,然後會出現很像蘋果smart bar的東西,那個東西點了後就能打開。

4.6 判斷是否安裝了APP及跳轉APP Store

  我們要做的時如果用戶安裝了APP就直接打開APP,如果沒有安裝就打開下載頁面或者進入應用市場讓用戶下載應用,但是在前端時無法通過js去判斷是否已經安裝了APP,解決辦法:
  1.用URL Scheme時用延時。設置3秒延時,如果用戶安裝了APP,3秒內沒有打開則進入下載頁面或應用市場,弊端是用URL Scheme會有詢問框“是否在XXXAPP中打開”,如果用戶3秒內沒有點擊,則頁面就跳轉到了下載頁。
  2.安卓端Chrome瀏覽器可以用intent配置S.browser_fallback_url來使沒有打開app時直接進入下載頁面。
  3.用Universal Links打開的頁面設置爲下載頁,下載頁裏放置下載按鈕,點擊下載按鈕進入應用市場。如果已經安裝了APP,則直接打開APP,如果沒有安裝,則這個下載url會被當作普通鏈接,瀏覽器就能打開下載頁,點擊下載按鈕,打開APP Store。

5.源碼

源碼地址:點擊下載

6.實現的功能

IOS實現功能:
1.在瀏覽器中點擊,若沒有安裝app,會跳轉到下載頁,點擊下載按鈕,打開itunes應用市場;
2.在瀏覽器中點擊,若安裝了app,則直接打開app;
3.在微信頁面中點擊按鈕,若沒有安裝app,會跳轉到下載頁,點擊下載按鈕,打開itunes應用市場;
4.在微信頁面中點擊按鈕,若安裝了app,則直接打開app;
5.在微信消息中直接點擊打開app的鏈接,可以直接打開app.(不是在微信瀏覽器中)
6.在記事本,短信,郵件中直接打開app

AOS實現功能:
1.在瀏覽器中點擊,若沒有安裝app,3秒會跳轉到下載頁;
2.在瀏覽器中點擊,若安裝了app,則直接打開app;
3.在Chrome瀏覽器,沒有 超過3秒後造成頁面跳轉到下載頁 的問題

發佈了86 篇原創文章 · 獲贊 151 · 訪問量 42萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章