背景
在iOS 9以前,我們從外部啟動App都是通過URL Scheme實現跳轉的。這種方式雖然可自定程度很高,能夠巧妙地實現很多跳轉,但弊端也很明顯:我們只能通過scheme://example這種格式的鏈接來實現跳轉,而且現在蘋果還對這種方式的跳轉加了一個提示框:“是否打開XXX”。對于對Web和原生App交互的場景需求量很大的產品來說,這樣的跳轉方式顯然是步驟冗雜的,用戶體驗并不好。
iOS 9以后,Universal Link的出現解決了這個問題。它所提供的直接、順暢、無縫銜接的跳轉能夠讓用戶體驗提升一個級別。用戶可以點擊開發者指定的類似于https://example.com/t
的URL直接喚醒App,而不需要在瀏覽器打開再點擊其他按鈕。
在你的App中添加這個功能很簡單:
- 在蘋果開發者網站中打開需要使用Universal Link功能的App中的Associated Domains
- 上傳apple-app-site-association到服務器根目錄下
- 在AppDelegate中實現相應的方法
配置
首先,我們要在蘋果開發者網站中開啟App的Associated Domains功能。
在Account -> Certificates, Identifiers & Profiles -> App IDs -> YourApp -> Edit中把Associated Domains設置為Enable
然后我們需要配置一下工程文件,找到Capabilities -> Associated Domains
打開此功能并把你需要跳轉的domain加進去,格式為applinks:www.example.com
部署
注意
首先你的服務器必須得支持SSL
接下來,我們需要上傳一個json文件到我們的服務器。json文件以apple-app-site-association命名
注意
文件不需要添加任何后綴
json的格式是這樣的:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TeamID.com.domain.App",
"paths":[ "*" ]
}
]
}
}
appID
:TeamID加上Bundle IDpaths
:支持Universal Link,也就是可以跳轉的路徑。*
代表此域名下所有路徑都支持,也可以具體制定到某個頁面例如/path/page
或者某個路徑下所有URL例如/path/*
關于paths
的配置,可以參考蘋果官方文檔
- Use * to specify your entire website
- Include a specific URL, such as /wwdc/news/, to specify a particular link
- Append * to a specific URL, such as /videos/wwdc/2015/*, to specify a section of your website
- In addition to using * to match any substring, you can also use ? to match any single character. You can combine both wildcards in a single path, such as /foo/*/bar/201?/mypage.
最后,我們只需要把配置好的json文件上傳到服務器中該域名的根目錄下,言下之意,我們可以用GET請求可以獲取到https://www.example.com/apple-app-association
再次強調必須是HTTPS協議
當我們的App在設備上第一次運行時,如果支持Associated Domains功能,那么iOS會自動去GET定義的Domain下的apple-app-site-association
文件。
需要留意iOS會先請求https://domain.com/.well-known/apple-app-site-association
如果此文件請求不到,再去請求https://domain.com/apple-app-site-association
所以如果想要避免服務器接收過多GET請求,可以直接把apple-app-site-association
放在./well-known/
目錄下
注意
服務器上
apple-app-site-association
的更新不會讓iOS本地的apple-app-site-association
同步更新,即iOS只會在App第一次啟動時請求一次,以后除非App更新或重新安裝否則不會在每次打開時請求apple-app-site-association
開發
待我們服務器部署好了,用curl測試一下apple-app-site-association
能夠正確GET到了,那么我們就需要在工程中響應跳轉事件了。
我們在AppDelegate中實現如下代理方法:
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{
具體實現:
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{
if (![userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
return YES;
}
//讀取url地址
NSURL *webUrl = userActivity.webpageURL;
if (![webUrl.path isEqualToString:@"/show"]) {
//path錯誤,直接從safari打開
[[UIApplication sharedApplication] openURL:webUrl];
return YES;
}
//跳轉并顯示內容
[[NSNotificationCenter defaultCenter] postNotificationName:@"notify" object:@"hello world"];
return YES;
}
這里的自由度就很高了,我們可以根據傳入的任何符合跳轉條件的URL進行不同的操作。
測試
現在一切都已經完成了,現在我們可以在短信中點擊一個URL直接跳轉到我們的App。至于如何檢驗URL是否能夠跳轉,一個快捷方便的方法就是在系統原生App中(如短信、郵件等)長按URL,如果彈出的選項中有在“your app”中打開,那么證明該URL是支持跳轉的。
注意
非系統原生App不一定能支持直接點擊URL跳轉,例如在微信中點擊URL會首先在微信內的WebView打開,如果要跳轉只能再通過Safari打開。