引言
最近在做客戶端開發(fā)的工作中,需要解決一些渠道流量監(jiān)控的問題。發(fā)現(xiàn)在喚醒app的時候涉及到很多這樣那樣的link,于是就先對這幾個link做了一些了解。
事實上,這幾個名詞并不是完全區(qū)分的關(guān)系,同時這些技術(shù)都仍處在不斷發(fā)展的階段,因此面對這樣碎片化的概念,很難去直接解釋清楚它們之間的關(guān)系與不同,所以只能先從每個名字的概念上和實踐運用中去把握了。
而且,這幾個概念實際上是有一些從屬和時間上的關(guān)系的,其實也不復(fù)雜,只是我們不光是要了解它們的意思,還得了解它們出現(xiàn)的情況,怎么使用。下面我就為大家簡單介紹:
1. Deep Link
Deep Link就是一個鏈接的概念,事實上我們每天都會使用到它去打開一個網(wǎng)站頁面,只不過它是比普通的鏈接更加復(fù)雜一些。在web開發(fā)領(lǐng)域,深度鏈接就是說這個鏈接不是僅僅打開一個網(wǎng)站http://example.com/, 而是直接地打開這個網(wǎng)站中的某個具體內(nèi)容頁面http://example.com/my-awesome-content-page 。 通常來講,有很多鏈接就是深度鏈接,只不過大家都習(xí)慣于稱之為鏈接。
在移動開發(fā)領(lǐng)域,深度鏈接的概念就是指app在處理特定的url時能夠直接跳轉(zhuǎn)到對應(yīng)的內(nèi)容頁面或者觸發(fā)特定的邏輯。這樣的好處有:
- 在web頁面和app的切換過程中保留了上下文
- App間的切換保留了上下文,實現(xiàn)app間參數(shù)的傳遞
- Web頁可以被搜索引擎索引,可以增加SEO的訪問量從而提高app下載量和開啟率。
Android、iOS都推出了相應(yīng)的概念去實現(xiàn)深鏈接。于是就有了Universal Link、App Link、URL schemes.
2. URI Schemes
URI、URL、URN
有興趣了解更多的話可以直接看這篇文章: The Difference Between URLs and URIs
這里我就直接捋一捋URI、URL、URN的關(guān)系。
首先,先看一下它們?nèi)齻€分別的英文全稱:
- URI : universal resource identifier
- URL : universal resource locator
- URN : universal resource name
這里可以看出,URI就是一個資源的統(tǒng)一標(biāo)志符,它既可以是定位符也可以是一個名稱,因此URL、URN都屬于URI。
如何區(qū)分URL和URN?
URL包含了找到資源的方法(路徑)和資源名稱,也就是當(dāng)一個URI包含了一個訪問機制或者網(wǎng)絡(luò)位置的時候(e.g. http// or ftp://),它就是一個URL了。
URN就是一個獨一無二的資源名稱,它是由urn開頭的一串URI。
e.g. urn:oasis:names:specification:docbook:dtd:xml:4.1.2
所以說,它們之間重要的區(qū)別就在于它的開頭,也就是Scheme.
URI Schemes
大家應(yīng)該都對http:// 非常熟悉,而它就是一個scheme,也就是一個url的開頭部分。
有興趣也可以去看我在之前寫過一篇關(guān)于URL scheme的介紹:iOS-URL Schemes 。而有了以上概念之后,我們可以了解到,實際上scheme不僅僅可以指URL的開頭,URI的開頭也一樣的是scheme。
那么回到正題,來講它和deep link的關(guān)系。URI Schemes其實就是實現(xiàn)deep linking的第一代解決方案。利用它就可以在移動開發(fā)中實現(xiàn)從web頁面或者別的app中喚起自己的app的功能,然而開發(fā)者們很快就發(fā)現(xiàn),這樣也還有很多限制:
- 當(dāng)要被喚起的app沒有安裝時,這個鏈接就會出錯。
- 當(dāng)注冊有多個scheme相同的時候,目前沒有辦法區(qū)分。
因此為了解決以上問題,蘋果和安卓都有了自己的第二套解決方案,分別是iOS的Universal Link,和安卓的App Link。
Custom URL Scheme
iOS在之前的很長一段時間內(nèi)用來實現(xiàn)deep linking以及app間通信的方法就是上面提到的,被叫做custom URL scheme。處理的方法就是:
- 注冊一個URL type,注冊的方法就是在app的info.plist文件里添加 CFBundleURLTypes 鍵,它包含了一個由多個字典組成的數(shù)組,每一個字典定義了這個app支持的一個URL scheme
Key | Value |
---|---|
CFBundleURLName | 一個包含了URL Scheme的抽象名字的字符串。為了保證它的唯一性,通常需要明確一個reverse-DNS的identifier,同時還應(yīng)該保證它的可讀性。 |
CFBundleURLSchemes | 一個包含了多個URL Scheme names的字符串?dāng)?shù)組。 |
- 用到
application:willFinishLaunchingWithOptions:
和application:didFinishLaunchingWithOptions:
這兩個方法去取回關(guān)于URL的信息同時決定是否要打開它。 - 在app delegate中實現(xiàn)入口方法:
application:openURL:sourceApplication:annotation:
或者application:openURL:options:
。前一個方法從iOS9后開始被淘汰,后一個方法是在iOS 9 之后引入的,若果沒有實現(xiàn)這個方法,在iOS 9 上也還是會向前兼容調(diào)用第一個老的方法,因此現(xiàn)在一般還是實現(xiàn)老方法)。
在iOS中,所有傳到app中的URL都是一個NSURL的對象,你可以定義URL的組成,但NSURL都遵守RFC 1808的一些規(guī)則,所以它支持大多數(shù)的傳統(tǒng)URL組成規(guī)則。NSURL類中還有能夠返回URL中的不同部分的方法,包括URL中的user、password、query、fragment、parameter strings等常見部分。
對于業(yè)務(wù)邏輯較少的app來說,可以直接通過url的字符串比較來區(qū)分業(yè)務(wù)邏輯。不過對于業(yè)務(wù)邏輯相對復(fù)雜,比如像現(xiàn)在開發(fā)團隊共同維護這塊邏輯的時候,就需要引入路由router來分發(fā)請求。在做上一個需求的時候有涉及,這里就不展開說了。
3. Universal Link
什么是Universal Link?
而iOS 9之后蘋果推出的一個替代之前的custom URL Scheme的新概念就是Universal Link。在蘋果開發(fā)者中可以看到對它的介紹是:
Seamlessly link to content inside your app, or on your website in iOS 9 or later. With universal links, you can always give users the most integrated mobile experience, even when your app isn’t installed on their device.
通俗講,就是用了這個Universal Link,就可以讓網(wǎng)站或者web view中的內(nèi)容在用戶點擊跳轉(zhuǎn)或安裝了app之后仍然能夠直接在這個app中被找到。比如,用戶在官網(wǎng)上點擊了“在app中瀏覽該商品”的鏈接,這個時候就可以通過Universal Link去喚起這個app,同時直接定位到該商品頁面。
它的實現(xiàn)機制與之前的Deep Link相似,只不過它不是只定義一個custom URL scheme,而是匹配了多個web頁面到app中相應(yīng)的位置,當(dāng)用戶打開某個匹配的頁面時,iOS會自動地將其重定向到app內(nèi)。
Universal Link的好處
接下來說Universal Link厲害的地方:
- 之前的Custom URL scheme是自定義的協(xié)議,因此在沒有安裝該app的情況下是無法直接打開的。而Universal Links本身也就是一個能夠指向一個web頁面或者app中的內(nèi)容頁的標(biāo)準(zhǔn)的web link(形如https://example.com) 因此能夠很好的兼容其他情況。也就是說,當(dāng)已經(jīng)安裝了這個app的時候,不需要加載任何web頁面,app就會立即啟動;當(dāng)這個app沒有安裝的時候,就會默認(rèn)地從當(dāng)前瀏覽器中重定向到App Store中引導(dǎo)用戶去下載安裝這個app。
- Universal links是從服務(wù)器上查詢是哪個app需要被打開,因此不存在Custom URL scheme那樣名字被搶占、沖突的情況。
- Universal links支持從其他app中的UIWebView中跳轉(zhuǎn)到目標(biāo)app
- 安全性,用universl link去打開的時候,只有你(開發(fā)這個app的人)可以通過創(chuàng)建和上傳一個允許這個網(wǎng)頁去通過這個URL去打開你的app的文件。
- 隱私性,提供Universal link給別的app進行app間的交流,然而對方并不能夠用這個方法去檢測你的app是否被安裝。(之前的custom scheme URL的canOpenURL方法可以,具體可以看這里iOS Review-DetectScheme。)
使用Universal Link
首先,你需要創(chuàng)建一個 apple-app-site-association文件,它是一些JSON格式的數(shù)據(jù),提供了你的app能夠處理的URLs。然后你需要將這個文件上傳到你的HTTPS web 服務(wù)器上。之后就是一些準(zhǔn)備工作來處理這個Universal Link,有兩種技術(shù),Web Browser–to–Native App Handoff 和 Shared Web Credentials Reference。
當(dāng)一個用戶點擊了這個universal link,iOS就會啟動你的app,然后會傳入一個NSUserActivity的對象,讓你能夠查詢到你的app是如何被啟動的。要實現(xiàn)這些,你需要做以下步驟:
- 添加一個權(quán)限(entitlement),用來具體說明你的app支持哪些域(domains)。
具體在xcode中,就是在Capabilities欄中找到Associated Domains,在里面添加以applinks:為前綴的域。如圖:
- 寫app delegate的方法,使之在收到NSUserActivity對象的時候能夠做出適當(dāng)?shù)捻憫?yīng)。尤其是
application:continueUserActivity:restorationHandler:
。
當(dāng)你的app在用戶點擊universal link后被啟動的時候,就會收到一個NSUserActivity對象,里面包括了值為NSUserActivityTypeBrowsingWeb的activityType。利用這個對象的webpageURL屬性中的URL,就可以知道用戶正在訪問的URL地址。另外,因為這個webpageURL屬性通常都會包括HTTP或者HTTPS URL,所以你還可以用NSURLComponents APIs去操縱這個URL的內(nèi)容。
Universal Link的缺陷
在講它的缺陷之前,我先介紹一下iOS的Universal link的一個機制:
在用戶點擊了Universal link之后,iOS會去檢測用戶最近一次是選擇了直接打開app還是打開網(wǎng)站。這個選擇的步驟,實際上是在用戶進入了app之后,頂部bar的右側(cè)會出現(xiàn)一個通過網(wǎng)站打開的按鈕選項。如圖:
因此,一旦用戶點擊了這個選項,他就會通過safiri打開你的網(wǎng)站。并且在之后的操作中,默認(rèn)一直延續(xù)這個選擇,除非用戶從你的webpage上通過點擊Smart App Banner上的OPEN按鈕來打開。也就是說,用戶非常容易在一次選擇之后,使得Universal link喚醒app的功能失效了。
4. Deferred Deep Link
然而,無論是URI Scheme還是Universal Link都沒有解決一個問題,就是如果設(shè)備上沒有安裝這個app的時候,保留住此時用戶停留的上下文。例如,利用Universal Link,在沒有安裝app的情況下,iOS能夠重定位到app store去引導(dǎo)用戶去下載安裝這個app,但是在安裝之后,app只能打開首頁,也就是說丟失了用戶在點擊跳轉(zhuǎn)進入app之前的那個頁面。
因此,有了一個非常重要的另一個概念:Deferred Deep Link。顧名思義,這里的deferred是延遲的意思,可以理解為延遲一下,在安裝過程中keep住跳轉(zhuǎn)前的特定頁面內(nèi)容,在app安裝之后,再利用這個link在app里進行跳轉(zhuǎn)。舉個例子,用戶在某個電商網(wǎng)站上看到一個商品,于是他點擊了一個按鈕“在app中查看該商品”,但他并沒有下載這個app,于是iOS就引導(dǎo)他到了App Store安裝這個app,當(dāng)他安裝完成之后,打開這個app,就會自動地在app中跳到他剛才想看的那個商品的頁面。這對于商家來說,也就大大提高了用戶的轉(zhuǎn)化率。
其他 Deep Link標(biāo)準(zhǔn)
這里介紹的主要都是針對于iOS開發(fā)中使用到的deep link標(biāo)準(zhǔn),那么對應(yīng)安卓開發(fā),同樣也有類似的標(biāo)準(zhǔn),大家可以自主了解:
- Facebook App Links
- Android App Links
- Chrome Intents
后話
目前,移動開發(fā)Deep Link領(lǐng)域?qū)嶋H上仍然是處于一種碎片式混亂的局面,有很多問題都還有待解決,距離達到一個工業(yè)級別的標(biāo)準(zhǔn)還很遠(yuǎn)。然而,利用現(xiàn)有的技術(shù)去不斷優(yōu)化用戶的體驗是每一個客戶端開發(fā)工程師的使命,所以我們沒有任何理由去抗拒變革,在目前沒有統(tǒng)一的標(biāo)準(zhǔn)的情況下,我們能夠做到的就是,應(yīng)用不同的標(biāo)準(zhǔn)去適應(yīng)所有可能的情況。