理解Deep Link & URI Schemes & Universal Link & App Link


https://www.jianshu.com/p/909999e398e6

 

引言

最近在做客戶端開發的工作中,需要解決一些渠道流量監控的問題。發現在喚醒app的時候涉及到很多這樣那樣的link,於是就先對這幾個link做了一些了解。
事實上,這幾個名詞並不是完全區分的關系,同時這些技術都仍處在不斷發展的階段,因此面對這樣碎片化的概念,很難去直接解釋清楚它們之間的關系與不同,所以只能先從每個名字的概念上和實踐運用中去把握了。
而且,這幾個概念實際上是有一些從屬和時間上的關系的,其實也不復雜,只是我們不光是要了解它們的意思,還得了解它們出現的情況,怎么使用。下面我就為大家簡單介紹:

1. Deep Link

Deep Link就是一個鏈接的概念,事實上我們每天都會使用到它去打開一個網站頁面,只不過它是比普通的鏈接更加復雜一些。在web開發領域,深度鏈接就是說這個鏈接不是僅僅打開一個網站http://example.com/, 而是直接地打開這個網站中的某個具體內容頁面http://example.com/my-awesome-content-page 。 通常來講,有很多鏈接就是深度鏈接,只不過大家都習慣於稱之為鏈接。
在移動開發領域,深度鏈接的概念就是指app在處理特定的url時能夠直接跳轉到對應的內容頁面或者觸發特定的邏輯。這樣的好處有:

  • 在web頁面和app的切換過程中保留了上下文
  • App間的切換保留了上下文,實現app間參數的傳遞
  • Web頁可以被搜索引擎索引,可以增加SEO的訪問量從而提高app下載量和開啟率。

Android、iOS都推出了相應的概念去實現深鏈接。於是就有了Universal Link、App Link、URL schemes.

2. URI Schemes

URI、URL、URN

有興趣了解更多的話可以直接看這篇文章: The Difference Between URLs and URIs
這里我就直接捋一捋URI、URL、URN的關系。
首先,先看一下它們三個分別的英文全稱:

  • URI : universal resource identifier
  • URL : universal resource locator
  • URN : universal resource name
    這里可以看出,URI就是一個資源的統一標志符,它既可以是定位符也可以是一個名稱,因此URL、URN都屬於URI。

如何區分URL和URN?

URL包含了找到資源的方法(路徑)和資源名稱,也就是當一個URI包含了一個訪問機制或者網絡位置的時候(e.g. http// or ftp://),它就是一個URL了。
URN就是一個獨一無二的資源名稱,它是由urn開頭的一串URI。
e.g. urn:oasis:names:specification:docbook:dtd:xml:4.1.2
所以說,它們之間重要的區別就在於它的開頭,也就是Scheme.

URI Schemes

大家應該都對http:// 非常熟悉,而它就是一個scheme,也就是一個url的開頭部分。
有興趣也可以去看我在之前寫過一篇關於URL scheme的介紹:iOS-URL Schemes 。而有了以上概念之后,我們可以了解到,實際上scheme不僅僅可以指URL的開頭,URI的開頭也一樣的是scheme。

那么回到正題,來講它和deep link的關系。URI Schemes其實就是實現deep linking的第一代解決方案。利用它就可以在移動開發中實現從web頁面或者別的app中喚起自己的app的功能,然而開發者們很快就發現,這樣也還有很多限制:

  • 當要被喚起的app沒有安裝時,這個鏈接就會出錯。
  • 當注冊有多個scheme相同的時候,目前沒有辦法區分。

因此為了解決以上問題,蘋果和安卓都有了自己的第二套解決方案,分別是iOS的Universal Link,和安卓的App Link。

Custom URL Scheme

iOS在之前的很長一段時間內用來實現deep linking以及app間通信的方法就是上面提到的,被叫做custom URL scheme。處理的方法就是:

  1. 注冊一個URL type,注冊的方法就是在app的info.plist文件里添加 CFBundleURLTypes 鍵,它包含了一個由多個字典組成的數組,每一個字典定義了這個app支持的一個URL scheme
Key Value
CFBundleURLName 一個包含了URL Scheme的抽象名字的字符串。為了保證它的唯一性,通常需要明確一個reverse-DNS的identifier,同時還應該保證它的可讀性。
CFBundleURLSchemes 一個包含了多個URL Scheme names的字符串數組。
  1. 用到application:willFinishLaunchingWithOptions:application:didFinishLaunchingWithOptions:這兩個方法去取回關於URL的信息同時決定是否要打開它。
  2. 在app delegate中實現入口方法:application:openURL:sourceApplication:annotation:或者application:openURL:options: 。前一個方法從iOS9后開始被淘汰,后一個方法是在iOS 9 之后引入的,若果沒有實現這個方法,在iOS 9 上也還是會向前兼容調用第一個老的方法,因此現在一般還是實現老方法)。

在iOS中,所有傳到app中的URL都是一個NSURL的對象,你可以定義URL的組成,但NSURL都遵守RFC 1808的一些規則,所以它支持大多數的傳統URL組成規則。NSURL類中還有能夠返回URL中的不同部分的方法,包括URL中的user、password、query、fragment、parameter strings等常見部分。
對於業務邏輯較少的app來說,可以直接通過url的字符串比較來區分業務邏輯。不過對於業務邏輯相對復雜,比如像現在開發團隊共同維護這塊邏輯的時候,就需要引入路由router來分發請求。在做上一個需求的時候有涉及,這里就不展開說了。

3. Universal Link

什么是Universal Link?

而iOS 9之后蘋果推出的一個替代之前的custom URL Scheme的新概念就是Universal Link。在蘋果開發者中可以看到對它的介紹是:

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,就可以讓網站或者web view中的內容在用戶點擊跳轉或安裝了app之后仍然能夠直接在這個app中被找到。比如,用戶在官網上點擊了“在app中瀏覽該商品”的鏈接,這個時候就可以通過Universal Link去喚起這個app,同時直接定位到該商品頁面。

它的實現機制與之前的Deep Link相似,只不過它不是只定義一個custom URL scheme,而是匹配了多個web頁面到app中相應的位置,當用戶打開某個匹配的頁面時,iOS會自動地將其重定向到app內。

Universal Link的好處

接下來說Universal Link厲害的地方:

  1. 之前的Custom URL scheme是自定義的協議,因此在沒有安裝該app的情況下是無法直接打開的。而Universal Links本身也就是一個能夠指向一個web頁面或者app中的內容頁的標准的web link(形如https://example.com) 因此能夠很好的兼容其他情況。也就是說,當已經安裝了這個app的時候,不需要加載任何web頁面,app就會立即啟動;當這個app沒有安裝的時候,就會默認地從當前瀏覽器中重定向到App Store中引導用戶去下載安裝這個app。
  2. Universal links是從服務器上查詢是哪個app需要被打開,因此不存在Custom URL scheme那樣名字被搶占、沖突的情況。
  3. Universal links支持從其他app中的UIWebView中跳轉到目標app
  4. 安全性,用universl link去打開的時候,只有你(開發這個app的人)可以通過創建和上傳一個允許這個網頁去通過這個URL去打開你的app的文件。
  5. 隱私性,提供Universal link給別的app進行app間的交流,然而對方並不能夠用這個方法去檢測你的app是否被安裝。(之前的custom scheme URL的canOpenURL方法可以,具體可以看這里iOS Review-DetectScheme。)

使用Universal Link

首先,你需要創建一個 apple-app-site-association文件,它是一些JSON格式的數據,提供了你的app能夠處理的URLs。然后你需要將這個文件上傳到你的HTTPS web 服務器上。之后就是一些准備工作來處理這個Universal Link,有兩種技術,Web Browser–to–Native App HandoffShared Web Credentials Reference

當一個用戶點擊了這個universal link,iOS就會啟動你的app,然后會傳入一個NSUserActivity的對象,讓你能夠查詢到你的app是如何被啟動的。要實現這些,你需要做以下步驟:

  • 添加一個權限(entitlement),用來具體說明你的app支持哪些域(domains)。
    具體在xcode中,就是在Capabilities欄中找到Associated Domains,在里面添加以applinks:為前綴的域。如圖:
 
Associated Domains
  • 寫app delegate的方法,使之在收到NSUserActivity對象的時候能夠做出適當的響應。尤其是application:continueUserActivity:restorationHandler:

當你的app在用戶點擊universal link后被啟動的時候,就會收到一個NSUserActivity對象,里面包括了值為NSUserActivityTypeBrowsingWeb的activityType。利用這個對象的webpageURL屬性中的URL,就可以知道用戶正在訪問的URL地址。另外,因為這個webpageURL屬性通常都會包括HTTP或者HTTPS URL,所以你還可以用NSURLComponents APIs去操縱這個URL的內容。

Universal Link的缺陷

在講它的缺陷之前,我先介紹一下iOS的Universal link的一個機制:
在用戶點擊了Universal link之后,iOS會去檢測用戶最近一次是選擇了直接打開app還是打開網站。這個選擇的步驟,實際上是在用戶進入了app之后,頂部bar的右側會出現一個通過網站打開的按鈕選項。如圖:

 
bar

因此,一旦用戶點擊了這個選項,他就會通過safiri打開你的網站。並且在之后的操作中,默認一直延續這個選擇,除非用戶從你的webpage上通過點擊Smart App Banner上的OPEN按鈕來打開。也就是說,用戶非常容易在一次選擇之后,使得Universal link喚醒app的功能失效了。

4. Deferred Deep Link

然而,無論是URI Scheme還是Universal Link都沒有解決一個問題,就是如果設備上沒有安裝這個app的時候,保留住此時用戶停留的上下文。例如,利用Universal Link,在沒有安裝app的情況下,iOS能夠重定位到app store去引導用戶去下載安裝這個app,但是在安裝之后,app只能打開首頁,也就是說丟失了用戶在點擊跳轉進入app之前的那個頁面。
因此,有了一個非常重要的另一個概念:Deferred Deep Link。顧名思義,這里的deferred是延遲的意思,可以理解為延遲一下,在安裝過程中keep住跳轉前的特定頁面內容,在app安裝之后,再利用這個link在app里進行跳轉。舉個例子,用戶在某個電商網站上看到一個商品,於是他點擊了一個按鈕“在app中查看該商品”,但他並沒有下載這個app,於是iOS就引導他到了App Store安裝這個app,當他安裝完成之后,打開這個app,就會自動地在app中跳到他剛才想看的那個商品的頁面。這對於商家來說,也就大大提高了用戶的轉化率。

其他 Deep Link標准

這里介紹的主要都是針對於iOS開發中使用到的deep link標准,那么對應安卓開發,同樣也有類似的標准,大家可以自主了解:

  • Facebook App Links
  • Android App Links
  • Chrome Intents

后話

目前,移動開發Deep Link領域實際上仍然是處於一種碎片式混亂的局面,有很多問題都還有待解決,距離達到一個工業級別的標准還很遠。然而,利用現有的技術去不斷優化用戶的體驗是每一個客戶端開發工程師的使命,所以我們沒有任何理由去抗拒變革,在目前沒有統一的標准的情況下,我們能夠做到的就是,應用不同的標准去適應所有可能的情況。



作者:Edie小哪吒
鏈接:https://www.jianshu.com/p/909999e398e6
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM