1.技術產(chǎn)生的背景?
明確的需求就是:手機打開我們的網(wǎng)站,點擊打開按鈕或者收藏按鈕,用戶如果已經(jīng)安裝app,跳轉(zhuǎn)到app做相應的操作。如果沒有安裝app,則跳轉(zhuǎn)到應用商店提示用戶下載安裝;或者 app跨域訪問app外部的瀏覽器的數(shù)據(jù)的方案,包括外部safari,或者QQ,微信,百度等外部app內(nèi)的瀏覽器。
- 設備指紋唯一識別方案(時間、IP、設備類型、操作系統(tǒng)版本,例如友盟SDK,缺點:存在誤傷)
- iOSSafariCookie互通方案(這種方案借助的是iOS9系統(tǒng)新出的一個系統(tǒng)APISFSafariViewController ,SafariAutoLoginTest
2.主要的應用場景?
Universal Links
Universal Links就是一個通用鏈接,iOS9以上的用戶,可以通過點擊這個鏈接無縫的重定向到一個app應用,而不需要通過safari打開跳轉(zhuǎn)。如果用戶沒有安裝這個app,則會在safari中打開這個鏈接指向的網(wǎng)頁。
Deeper Link
用戶在別的wap網(wǎng)頁上,產(chǎn)生了用戶行為,用戶數(shù)據(jù),但是還沒下載app,當用戶下載app后,打算直接在app內(nèi)延續(xù)之前在wap上的行為和數(shù)據(jù)的時候,就需要運用到跨越瀏覽器與app鴻溝的,互通方案。
簡單舉個例子就是:
用戶在微信瀏覽器里,訪問某個頁面感興 趣并且登陸了,然后引導下載了app,等用戶下載完app后第一次打開,希望能自動就完成登陸,甚至同步下來一些剛才用戶在wap頁面上操作的數(shù)據(jù)
如果能發(fā)生跨瀏覽器與app的互通,除了這個case之外,還可以有更多地自由發(fā)揮,設計出更加舒暢的用戶體驗;這就是 Deeper Link
3.實現(xiàn)的原理?
當有安裝app時:用戶先去瀏覽wap頁面,wap頁面觸發(fā)了url跳轉(zhuǎn),自動喚起了已經(jīng)安裝的app,并且伴隨著url傳遞來了數(shù)據(jù),一氣呵成,沒錯用戶很自然的從wap上的操作行為,延續(xù)到了app上.
-
當沒有安裝app時:需要跨越沙盒傳遞數(shù)據(jù),deferred deep link(延遲深度鏈接)
- 1.用戶通過safari瀏覽wap站,wap站寫用戶行為數(shù)據(jù)進入cookie.
- 2.用戶通過引導下載app,運行app.
- 3.第一次運行app,app內(nèi)靜默的打開一個純透明safari(讓用戶感覺不出來).
- 4.純透明的safari訪問一個專門用來靜默取cookie得頁面.
- 5.純透明的safari訪問的取cookie的頁面,取到了正確的cookie數(shù)據(jù).
- 6.純透明的safari將數(shù)據(jù)通過openurl,靜默的回傳給app.
- 7.app拿到瀏覽器數(shù)據(jù)后,銷毀無用的純透明safari.
4.有哪些突出的優(yōu)勢?
- 用戶體驗好
- 不會出現(xiàn)誤傷即匹配出錯的問題
5.如何配置來應用此技術?
按照蘋果官方文檔來說,支持通用鏈接非常簡單喲,只需要三步
- 1.創(chuàng)建一個名字叫做apple-app-site-association,包含固定格式的json文件
- 2.將這個文件上傳到你的服務器,可以將這個文件放到服務器的根目錄下,也可以放到.well-known這個子目錄下。
- 3.配置app,然后在app里面添加代理方法
具體方法
- 1.apple-app-site-association文件
{
"applinks": {
"apps": [],
"details": [
{
"appID": "teamID.bundleId”,
"paths": ["/deaplink","/wwdc/news/","*"]
},
{
"appID": "ABCD1234.com.apple.wwdc",
"paths": [ "*" ]
}
]
}
}
- appID 的 格式為 teamID.bundleId形式。
- paths配置,實際上就是限制哪些路徑可以喚醒app,哪些路徑不能喚醒app。使用*配置,則整個網(wǎng)站都可以使用
蘋果驗證通用鏈接是否可用的網(wǎng)站:https://search.developer.apple.com/appsearch-validation-tool/
- 2.app id 配置
app IDs 配置,進入開發(fā)者網(wǎng)站,找到你自己的bundleId,可以點擊edit按鈕,開啟associate domains,如下圖

-
3.項目配置,在項目的Capablities中開啟Associated domains,如下圖:
 .png
6.配置時需注意哪些點?

- apple-app-site-association文件名字必須為apple-app-site-association,不能帶后綴名,有的電腦設置的隱藏后綴名,這點需要注意。
- 配置的paths路徑,是區(qū)分大小寫的
- 注意domains可以添加多個,前綴必須為applinks:,applinks:后為你的服務器的域名。
- 快捷驗證,在備忘錄中輸入https://yourdomain.com/apple-app-site-association,長按這個鏈接,出現(xiàn)上圖提示則配置成功。
Alt text
- 服務器必須要支持https,而且需要支持TLS1.2協(xié)議以上,不過相信蘋果強制支持https之后,這個坑就會慢慢填上了?,F(xiàn)在還有很多童鞋的服務器使用的免費的證書,或者證書不被蘋果信任,然后就會導致無法下載apple-app-site-association。蘋果支持的https根證書列表(https://support.apple.com/en-us/HT204132)
- 只支持iOS9以上
- 使用charles抓包顯示,只有初次安裝app時才會去請求apple-app-site-association文件,所以測試時有可能因為網(wǎng)絡波動導致apple-app-site-association文件獲取失敗。這種情況,多卸載幾次,安裝時使用4G。
- 驗證各種配置的還有一個網(wǎng)站,需要打成ipa包丟上去。
7.處理跳轉(zhuǎn)的核心代碼
代碼接收Universal Links喚醒
-(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{
NSLog(@"userActivity : %@",userActivity.webpageURL.description);
return YES;
}
在appdelegate中實現(xiàn)上面這個方法,當使用Universal Links喚醒app時就執(zhí)行這個方法;接下來就是打開一個透明safari,等待來自網(wǎng)頁的openurl跳轉(zhuǎn)。制作透明safari的方法就是new出來后,alpha改為0,直接present。
-(void)VKGetSafariInfo:(VKSafariReturn)rtBlock {
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0) {
if (rtBlock) {
self.rtblock = rtBlock;
SFSafariViewController *safari = [[SFSafariViewController alloc]initWithURL:self.safariUrl];
safari.delegate = self;
safari.modalPresentationStyle = UIModalPresentationOverCurrentContext;
safari.view.alpha = 0.0f;
self.safari = safari;
UIViewController *currentVC = [self getCurrentVC];
self.currentVC = currentVC;
[currentVC presentViewController:safari animated:NO completion:nil];
}
}else{
if (rtBlock) {
rtBlock(NO,nil);
}
}
}
當透明safari加載完畢后,略微延遲后直接銷毀safari,如果在延遲期間,openurl返回則判斷,取cookie數(shù)據(jù)成功,回調(diào)成功,如果超時,就判斷取cookie數(shù)據(jù)失敗,回調(diào)失敗。
此處是SFSafariViewController的delegate回調(diào):
-(void)safariViewController:(SFSafariViewController *)controller didCompleteInitialLoad:(BOOL)didLoadSuccessfully{
__weak typeof(self) weakself = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.timeOut * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[weakself.currentVC dismissViewControllerAnimated:NO completion:^{
weakself.safari = nil;
weakself.currentVC = nil;
}];
[weakself VKTimeOut];
});
}
8.待解決問題
- wap 端如何判斷一個app 是否安裝
- 如何跳轉(zhuǎn)到app store或者安裝的app上
9. 參考文檔?
SupportUniversalLinks
deepLink iOS 應用到自己APP 記錄
iOS9 Universal Links踩坑之旅,移動應用之deeplink喚醒app
簡單的Mac-Custom-URL-Scheme-demo
deeplink的一點簡單研究
