深度鏈接 Deep Link


 

 目的 

本文檔用於幫助客戶一步一步實施深度鏈接,不論是Android還是iOS系統,自定義的、或者更高 級的App Link / Universal Link。希望幫助客戶實施用戶召回這個方案上掃清障礙。

 背景介紹 

2015年的Google I/O大會上推出的Universal App Campaigns距今已經有4年多了,客戶伴隨着 UAC1.0, 2.0, 2.5, 3.0的產品迭代,或多或少完成了自己獲取新客戶的需求,當下一個迫切的需求 就是如何召回老用戶繼續使用我的App。基於這樣的業務需求,Google今年推出了App  Campaigns for Engagement這款產品來幫助廣告主召回老用戶。要想使用這款產品,有三個條 件是必不可少的: 

  1. 深度鏈接 
  2. 創建受眾用戶列表 
  3. 做好轉化追蹤 

其中深度鏈接是這三個條件當中相對來說比較復雜的一環,所以本文檔會一步一步交給大家如何 正確實施適用於Google ACe的深度鏈接。 

概覽 

文檔會分別介紹Android和iOS基於Custom Scheme的深度鏈接和App Link / Universal Link的技術 方案,並且提供給開發者如何去驗證你的深度連接是否工作。 

深度鏈接(Deep Link) 

什么是深度鏈接?通俗地講,他是指移動端應用在處理特定URI的時候可以直接跳轉到對應的內容 頁或出發特定邏輯,而不僅僅是啟動App。深度鏈接的好處是可以提高用戶的打開轉化率,便於 用戶訪問,提高用戶體驗,傳播更方便,為營銷提供了一種全新的工具。  目前處理深度鏈接主要有兩種方式:Custom URI Schemes和App / Universal Links. 以下也會分別 介紹不同技術方案的實現方式和優缺點。 

自定義 URI Schemes 

在App / Universal Links出現以前,Android和iOS都采用的URI Schemes的方式來處理深度。使用 這種方式實現的有點是易於開發,可同時適用於Android和iOS系統。缺點是不安全,技術比較落 后,用戶體驗不是特別好。 

iOS Custom URI Scheme 

要想在iOS上實現自定義URI scheme,需要完成以下三個步驟: 

  1. 定義你的app的URL格式 
  2. 注冊你的scheme 
  3. 在app內處理打開URL的業務邏輯 

如何定義URL 

URL一定要以scheme名稱開頭,既然是自定義URI scheme,按就要保證自己app的scheme是獨 一無二的,不要跟同一設備里的其他app scheme重名,例如我們是做photo的開發者,可以定義 scheme為myphotoapp。 

注冊URL Scheme 

注冊你的URL scheme,以便讓app知道哪些URL是可以被app直接打開的。在Xcode中打開 info.plist文件 

  1.  在Information Property List下添加URL types  
  2.  添加URL Schemes,例如:myphotoapp 
  3.  添加URL identifier,例如:com.example.myphotoapp 
  4.  添加Document Role, Viewer, 如圖:

 

在應用內處理URL 

當以上都組做完之后,就可以在應用內開發處理URL的業務邏輯了。在iOS里是使用 application(_:open:options:)方法來實現的。實例代碼如下:  

 1 func​ ​application(​_​ application: UIApplication,
 2                   ​open​ url: URL,
 3                   options: [UIApplicationOpenURLOptionsKey : ​Any​] = [:] )​ -> ​Bool​ {
 4      ​// Determine who sent the URL.
 5      ​let​ sendingAppID = options[.sourceApplication]
 6      ​print​(​"source application = \(sendingAppID ?? "​Unknown​")"​)
 7      ​// Process the URL.
 8      ​guard​ ​let​ components = ​NSURLComponents​(url: url, resolvingAgainstBaseURL: ​true​), 
 9         ​let​ albumPath = components.path,         ​
10         let​ params = components.queryItems ​else​ {             
11             ​print​(​"Invalid URL or album path missing"​)             
12return​ ​false     
13     }         ​
14     if​ ​let​ photoIndex = params.first(​where​: { $​0​.name == ​"index"​ })?.value {
15         ​print​(​"albumPath = \(albumPath)"​)         ​
16         print​(​"photoIndex = \(photoIndex)"​)         
17return​ ​true     
18     } ​else​ {        
19     ​    print​(​"Photo index missing"​)         ​
20         return​ ​false     
21 22 }   

  

Android Custom URI Scheme 

Android系統的深度鏈接需要完成以下步驟: 

  1.  在manifest中添加intent filter 
  2.  解析intent filter內容 
  3.  測試深度鏈接 

在manifest中添加Intent Filters 

要想開發一個可以打開你的應用的連接,需要在manifest文件中添加包含elements和attribute的 值到intent filter里: 

<action>:​ 請使用ACTION_VIEW intent action,這樣才能讓Google Search搜索到。 

<category>:​ 請包含BROWSABLE和DEFAULT category, 這樣才能讓你的app被瀏覽器訪問到。 

<date>:​ data tag里必須包含​android:scheme  例如一個深度鏈接的URI是: ​example://gizmos​,那么intent filter應該是這樣的 

 1 <activity     ​
 2     android:name​=​"com.example.android.GizmosActivity"     ​
 3     android:label​=​"@string/title_gizmos"​ ​>
 4     <intent-filter​ ​android:label​=​"@string/filter_view_example_gizmos"​>         
 5         ​<action​ ​android:name​=​"android.intent.action.VIEW"​ ​/>         ​
 6         <category​ ​android:name​=​"android.intent.category.DEFAULT"​ ​/>         ​
 7         <category​ ​android:name​=​"android.intent.category.BROWSABLE"​ ​/>         
 8         ​<!-- Accepts URIs that begin with "example://gizmos” -->         
 9         ​<data​ ​android:scheme​=​"example"               ​
10             android:host​=​"gizmos"​ ​/>     ​
11     </intent-filter>  
12 </activity> 

 解析Intent Filter內容 

通過調用getData()和getAction()可以獲取Intent的Data和Action。請參考以下Java代碼示例: 

1 @Override  
2 public​ ​void​ onCreate(​Bundle​ savedInstanceState) {
3     ​super​.onCreate(savedInstanceState);
4     setContentView(R.layout.main);
5        
6     ​Intent​ intent = getIntent();     ​
7     String​ action = intent.getAction();     ​
8     Uri​ data = intent.getData();  
9

 測試深度鏈接 

可以使用​Android Debug Bridge​和Activity Manager工具來測試深度鏈接是否可以實現正確的 app操作。可以在設備或者模擬器上運行adb命令,示例如下:  

1 $ adb shell am start        
2  -W -a android.intent.action.VIEW         
3 -d <URI> <PACKAGE>  

 更多信息請參考 官方文檔 

Custom Scheme 測試工具 

1. 安裝app並打開至少一次。 

2. 用手機瀏覽器打開​https://appdevdeeplink.firebaseapp.com/ 

3. 輸入你的Custom Scheme URL,點擊​“Generate Deep Link” 

4. 點擊生成的藍色按鈕。如果深度鏈接配置正確,將可以打開你的app。  

 

 

 

App / Universal Links 

隨着技術的演進,2015年的時候,Android和iOS分別發布新的技術來支持深度鏈接,Android陣 營是App Links,iOS陣營是Universal Links,才使得開發深度鏈接更加便捷、安全和高效。就應 用開發的安全性和面向未來的兼容性而言,我們強烈推薦采用App / Universal Links的方式開發深 度鏈接。 

iOS 

實現iOS通用鏈接(深度鏈接)需要有一個域名,並且網站是支持HTTPS協議。打開深度鏈接時,  iOS 會檢查該設備已安裝的應用是否在這一域中被否注冊了,如果已注冊,App 將立即啟動,無 需加載網頁。否則,網頁 URL (可以簡單重定向到 App Store)將在 Safari 瀏覽器中加載。   

配置​iOS深度鏈接需要完成以下3個步驟: 

  1.  創建apple-app-site-association文件,其中包含app可以處理URL,內容為JSON格式。 
  2.  將apple-app-site-association上傳至你的服務器,將文件放在根目錄或 .well-known子目 錄下。 
  3.  准備好你的app。   

創建並上傳Association File 

每個包含不同內容的域名需要一個單獨的​apple-app-site-association​ 文件,沒有后綴名。iOS版本 9.3.1以上的,未壓縮的​apple-app-site-association​ 文件大小不能超過128kb。  在​apple-app-site-association​ 文件中,你需要指定使用深度鏈接的路徑(path)。以下示例展示了3條 路徑均要被處理為深度鏈接的情況: 

 1  2     "applinks": {        
 3         "apps": [],        
 4         "details": [            
 5  6                 "appID": "9JA89QQLNQ.com.apple.wwdc" 7                 "paths": [ "/wwdc/news/", "/videos/wwdc/2015/*" 8             },            
 9 10                 "appID": "ABCD1234.com.apple.wwdc"11                 "paths": [ "*"12 13 14     }  
15 }

 因為系統會按path數組的順序評估,因而需要將高優先級的path放在前面。有多種指定path的方法: 

  1.  用*來代替所有網頁 
  2.  指定一個特定的URL, 比如加上 ​/wwdc/news/ 
  3.  除了可以用*之外,還可以用?來匹配單一字符   

創建完​ ​apple-app-site-association​文件之后,需要將它上傳至服務器根目錄或者​ ​.well-known​ 目錄 下。這個文件需要可以直接通過HTTPS訪問而不經過任何跳轉。  

准備App來測試深度鏈接 

當一個用戶點擊深度鏈接的時候,就會進入app了。iOS會觸發app來發送NSUserActivity請求來 獲取此app打開的方法。在你的app里使用深度鏈接,你需要完成下列步驟: 

  1.  Entitlement文件包含你的域名信息,將此文件加入到app support中。 
  2.  為app指定收到NSUserActivity請求時的響應處理。   

首先打開工程配置中的Associated Domains,並添加支持的域名,前綴是applinks:,例如 applinks:www.mywebsite.com​.   

 

 

 指定好域名之后,你需要采用UIApplicationDelegate方法( application:continueUserActivity:restorationHandler:​)使得你的app可以收到和處理請求。  當用戶點擊深度鏈接之后,會收到​NSUserActivity​ ​類型為​activityType​,​值為 NSUserActivityTypeBrowsingWeb​的請求。參考代碼如下 

 1 @UIApplicationMain  
 2 class AppDelegate: UIResponder, UIApplicationDelegate {         
 3 
 4     var window: UIWindow?     
 5     func application(_ application: UIApplication, continue userActivity: NSUserActivity,                      
 6         restorationHandler: @escaping ([Any]?) -> Void) -> Bool {             
 7     if userActivity.activityType == NSUserActivityTypeBrowsingWeb {             
 8         let webpageURL = userActivity.webpageURL             
 9         print("點擊的鏈接是:\(webpageURL)")                 
10         
11         //......         
12 13     return true     
14 }

 

 更多信息請參考官方文檔

iOS 深度鏈接測試 

1. 打開 ​https://search.developer.apple.com/appsearch-validation-tool/ 

2. 輸入你的深度鏈接URL,並點擊搜索按鈕 

3. 查看你的報告結果 (以https://maps.google.com為例)  

 

Android  

注:

url scheme =對應android幫助文檔中deeplink和深層鏈接

app links = 對應android幫助文檔中applinks 和 應用連接

應用鏈接是一種深層鏈接,它們基於已驗證屬於您網站的網站網址。因此,點擊某個此 類鏈接會立即打開您的應用(如已安裝),並且彈出選擇應用程序的對話框。自定義scheme的 深度鏈接是一種 intent 過濾器,可讓用戶直接進入 Android 應用中的特定 Activity。點擊此類鏈 接可能會打開一個應用程序選擇對話框,該對話框可以讓用戶從多個能夠處理給定網址的應用 (包括您的應用)中選擇一個。

例如,圖 顯示的是在用戶點擊地圖鏈接后打開的對話框,該對 話框會詢問用戶是在 Google 地圖中還是 Chrome 中打開此鏈接 

 

 

 

 

 

以下列表介紹了App Link與自定義URI Scheme的關系:

 

 

Android系統的深度鏈接需要完成以下步驟:

  1.  在manifest中添加intent filter
  2.  解析intent filter內容
  3.  聲明網站與應用
  4.  測試深度鏈接

當app收到網頁鏈接訪問請求時,安卓系統會優先用用戶偏好的app打開此鏈接。若無此偏好設置 ,則會用唯一可以使用的app打開,最后才會讓用戶從對話框列表中自己選擇。

Manifest文件的配置和Intent Handler定義了app和網頁之間的鏈接和活動內容。

在manifest中添加Intent Filters

下面的XML代碼展示了如何添Iintent Filter來實現深度鏈接,由此可以實現打開URI “http://www.example.com/gizmos”。 

 1 <activity
 2     android:name="com.example.android.GizmosActivity"
 3     android:label="@string/title_gizmos" >
 4     <intent-filter android:label="@string/filter_view_http_gizmos">
 5         <action android:name="android.intent.action.VIEW" />
 6         <category android:name="android.intent.category.DEFAULT" />
 7         <category android:name="android.intent.category.BROWSABLE" />
 8         <!-- Accepts URIs that begin with "http://www.example.com/gizmos” -->
 9         <data android:scheme="http"
10             android:host="www.example.com"
11             android:pathPrefix="/gizmos" />
12         <!-- note that the leading "/" is required for pathPrefix-->
13     </intent-filter>
14 </activity>

 解析Intent Filter內容

通過調用getData()和getAction()可以獲取Intent的Data和Action。請參考以下Java代碼示例:

1 @Override
2 public void onCreate(Bundle savedInstanceState) {
3     super.onCreate(savedInstanceState);
4     setContentView(R.layout.main);
5     
6     Intent intent = getIntent();
7     String action = intent.getAction();
8     Uri data = intent.getData();
9 }

 聲明網站與應用

Android 應用鏈接是一種特殊類型的深層鏈接,可讓您的網站網址直接在您的 Android 應 用中打開相應內容(無需用戶選擇應用)。

要向應用添加 Android 應用鏈接,請定義使用 HTTP 網址打開應用內容的 intent 過濾器 (如解析Intent Filter中所述),並驗證您是否為相關應用和網站網址的所有者。如果系 統成功驗證您是網址所有者,則會自動將這些網址 intent 路由到您的應用。

要驗證您對應用和網站的所有權,您需要執行以下步驟:

  •  在清單中請求自動驗證應用鏈接。這樣即可向 Android 系統說明其應該驗證您的 應用是否屬於 intent 過濾器中使用的網址網域。
  •  通過在以下位置托管 Digital Asset Links JSON 文件,聲明您的網站和 intent 過濾 器之間的關系:https://domain.name/.well-known/assetlinks.json

請求應用鏈接驗證

要為您的應用啟用鏈接處理驗證,請在應用清單內的網址 intent 過濾器中設置 android:autoVerify="true",所選的過濾器可以是具有 android.intent.action.VIEW intent 操作 並屬於 android.intent.category.BROWSABLE intent 類別的任意過濾器,如以下清單代碼段 所示:

1 <activity ...>
2     <intent-filter android:autoVerify="true">
3         <action android:name="android.intent.action.VIEW" />
4         <category android:name="android.intent.category.DEFAULT" />
5         <category android:name="android.intent.category.BROWSABLE" />
6         <data android:scheme="http" android:host="www.example.com" />
7         <data android:scheme="https" />
8     </intent-filter>
9 </activity>

 如果您的任一 intent 過濾器中存在 android:autoVerify="true",則在搭載 Android 6.0 及更 高版本的設備上安裝您的應用會導致系統嘗試驗證與應用的任何 intent 過濾器中的網址 相關聯的所有主機。驗證涉及以下方面:

  1.  系統會檢查所有包含以下各項的 intent 過濾器:
    1.   
      • 操作:android.intent.action.VIEW 
      • 類別:android.intent.category.BROWSABLE 和 android.intent.category.DEFAULT 
      • 網絡協議:http 或 https
  2.  對於在上述 intent 過濾器中找到的每個唯一主機名,Android 會在相應網站上查詢 位於 https://hostname/.well-known/assetlinks.json 的 Digital Asset Links 文件。

僅當系統為清單中的所有主機找到匹配的 Digital Asset Links 文件后,才會將您的應用確 立為處理指定網址模式的默認處理程序。

支持多個主機的應用鏈接

系統必須能夠對照每個相應網域上托管的 Digital Asset Links 文件驗證應用網址 intent 過 濾器的 元素中指定的每個主機。如果任何驗證失敗了,應用便無法通過驗證,因 此不能成為應用 intent 過濾器中定義的任何網址模式的默認處理程序。然后,系統會默 認采用標准行為來解析相應 intent。

例如,如果在 https://www.example.com/.well-known/assetlinks.json 或 https://www.example.net/.well-known/assetlinks.json 未找到 assetlinks.json 文件,則具有以 下 intent 過濾器的應用無法通過驗證: 

 1     <application>
 2 
 3       <activity android:name=”MainActivity”>
 4         <intent-filter android:autoVerify="true">
 5           <action android:name="android.intent.action.VIEW" />
 6           <category android:name="android.intent.category.DEFAULT" />
 7           <category android:name="android.intent.category.BROWSABLE" />
 8           <data android:scheme="http" android:host="www.example.com" />
 9           <data android:scheme="https" />
10         </intent-filter>
11       </activity>
12       <activity android:name=”SecondActivity”>
13         <intent-filter>
14           <action android:name="android.intent.action.VIEW" />
15           <category android:name="android.intent.category.DEFAULT" />
16           <category android:name="android.intent.category.BROWSABLE" />
17           <data android:scheme="https" android:host="www.example.net" />
18         </intent-filter>
19       </activity>
20 
21     </application>
22     

 請注意,同一 intent 過濾器中的所有 元素會合並在一起以涵蓋合並后屬性的所有 變體。例如,上面的第一個 intent 過濾器包含一個僅聲明 HTTPS 協議的 元素。但 是,該元素與其他 元素組合在一起,所以此 intent 過濾器支持 http://www.example.com 和 https://www.example.com。因此,如果您想要定義 URI 協議和 網域的特定組合,則必須創建單獨的 intent 過濾器。 

支持多個子網域的應用鏈接

Digital Asset Links 協議將 intent 過濾器中的子網域視為唯一的獨立主機。因此,如果您的 intent 過濾器列出多個包含不同子網域的主機,您必須在每個網域上分別發布一個有效的 assetlinks.json。例如,以下 Intent 過濾器包含 www.example.com 和 mobile.example.com 作為接受的 intent 網址主機。因此,必須在 https://www.example.com/.well-known/assetlinks.json 和 https://mobile.example.com/.well-known/assetlinks.json 上發布有效的 assetlinks.json。

 1     <application>
 2       <activity android:name=”MainActivity”>
 3         <intent-filter android:autoVerify="true">
 4           <action android:name="android.intent.action.VIEW" />
 5           <category android:name="android.intent.category.DEFAULT" />
 6           <category android:name="android.intent.category.BROWSABLE" />
 7           <data android:scheme="https" android:host="www.example.com" />
 8           <data android:scheme="https" android:host="mobile.example.com" />
 9         </intent-filter>
10       </activity>
11     </application>
12     

 或者,如果您使用通配符(例如 *.example.com)聲明主機名,則必須在根主機名 (example.com) 上發布 assetlinks.json 文件。例如,只要將 assetlinks.json 文件發布到 https://example.com/.well- known/assetlinks.json,具有以下 intent 過濾器的應用就會通過針對 example.com 的任何子域名(如 foo.example.com)的驗證:

 1 <application>
 2       <activity android:name=”MainActivity”>
 3         <intent-filter android:autoVerify="true">
 4           <action android:name="android.intent.action.VIEW" />
 5           <category android:name="android.intent.category.DEFAULT" />
 6           <category android:name="android.intent.category.BROWSABLE" />
 7           <data android:scheme="https" android:host="*.example.com" />
 8         </intent-filter>
 9       </activity>
10     </application>

 您必須在網站上發布 Digital Asset Links JSON 文件,以指示與網站相關聯的 Android 應用並驗證應用的網址 intent。JSON 文件使用下列字段標識關聯的應用:

聲明網站關聯性

package_name:在應用的 build.gradle 文件中聲明的應用 ID
sha256_cert_fingerprints:應用的簽名證書的 SHA256 指紋。您可以利用 Java 密鑰工具,通過以下命令生成該指紋:

$ keytool -list -v -keystore my-release-key.keystore

 此字段支持多個指紋,這些指紋可用於支持不同版本的應用,例如調試版 build 和正式版 build。

 

以下 assetlinks.json 示例文件可為 com.example Android 應用授予鏈接打開權限:

1  [{
2       "relation": ["delegate_permission/common.handle_all_urls"],
3       "target": {
4         "namespace": "android_app",
5         "package_name": "com.example",
6         "sha256_cert_fingerprints":
7         ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
8       }
9     }]

 將網站與應用關聯

需要將網站在assetlinks.json文件中聲明與應用的關聯性。一下文件展示了如何聲明 example.com與app1的關聯性。 https://www.example.com/.well-known/assetlinks.json

1 [{
2       "relation": ["delegate_permission/common.handle_all_urls"],
3       "target": {
4         "namespace": "android_app",
5         "package_name": "com.example",
6         "sha256_cert_fingerprints":
7         ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
8       }
9     }]

 發布JSON驗證文件

您必須在以下位置發布 JSON 驗證文件: https://domain.name/.well-known/assetlinks.json

請確保以下幾點:

  • 使用內容類型 application/json 發布 assetlinks.json 文件。 
  • 無論應用的 intent 過濾器是否將數據協議聲明為 HTTPS,都必須可通過 HTTPS 連 接訪問 assetlinks.json 文件。 
  • assetlinks.json 文件必須可直接訪問,沒有任何重定向(無 301 或 302 重定向), 並且漫游器可訪問(您的 robots.txt 必須允許抓取 /.well-known/assetlinks.json)。 
  • 如果您的應用鏈接支持多個主機網域,則必須在每個網域上分別發布 assetlinks.json 文件。 
  • 請勿發布清單文件中的開發/測試網址無法供公眾訪問的應用(例如,任何只可通 過 VPN 訪問的應用)。

Android 應用鏈接測試

可以使用Android Debug Bridge和Activity Manager工具來測試深度鏈接是否可以實現正確的 app操作。可以在設備或者模擬器上運行adb命令,示例如下:

1 adb shell am start -a android.intent.action.VIEW \
2         -c android.intent.category.BROWSABLE \
3         -d "http://domain.name:optional_port"

 更多信息請參考官網文檔


免責聲明!

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



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