1.技術(shù)產(chǎn)生的背景堪旧?
明確的需求就是:手機(jī)打開我們的網(wǎng)站涩禀,點(diǎn)擊打開按鈕或者收藏按鈕,用戶如果已經(jīng)安裝app咆繁,跳轉(zhuǎn)到app做相應(yīng)的操作讳推。如果沒有安裝app,則跳轉(zhuǎn)到應(yīng)用商店提示用戶下載安裝玩般;或者 app跨域訪問app外部的瀏覽器的數(shù)據(jù)的方案银觅,包括外部safari,或者QQ坏为,微信究驴,百度等外部app內(nèi)的瀏覽器。
- 設(shè)備指紋唯一識別方案(時(shí)間匀伏、IP洒忧、設(shè)備類型、操作系統(tǒng)版本够颠,例如友盟SDK熙侍,缺點(diǎn):存在誤傷)
- iOSSafariCookie互通方案(這種方案借助的是iOS9系統(tǒng)新出的一個(gè)系統(tǒng)APISFSafariViewController ,SafariAutoLoginTest
2.主要的應(yīng)用場景履磨?
Universal Links
Universal Links就是一個(gè)通用鏈接核行,iOS9以上的用戶,可以通過點(diǎn)擊這個(gè)鏈接無縫的重定向到一個(gè)app應(yīng)用蹬耘,而不需要通過safari打開跳轉(zhuǎn)芝雪。如果用戶沒有安裝這個(gè)app,則會在safari中打開這個(gè)鏈接指向的網(wǎng)頁综苔。
Deeper Link
用戶在別的wap網(wǎng)頁上惩系,產(chǎn)生了用戶行為位岔,用戶數(shù)據(jù),但是還沒下載app堡牡,當(dāng)用戶下載app后抒抬,打算直接在app內(nèi)延續(xù)之前在wap上的行為和數(shù)據(jù)的時(shí)候,就需要運(yùn)用到跨越瀏覽器與app鴻溝的晤柄,互通方案擦剑。
簡單舉個(gè)例子就是:
用戶在微信瀏覽器里,訪問某個(gè)頁面感興 趣并且登陸了芥颈,然后引導(dǎo)下載了app惠勒,等用戶下載完app后第一次打開,希望能自動就完成登陸爬坑,甚至同步下來一些剛才用戶在wap頁面上操作的數(shù)據(jù)
如果能發(fā)生跨瀏覽器與app的互通纠屋,除了這個(gè)case之外,還可以有更多地自由發(fā)揮盾计,設(shè)計(jì)出更加舒暢的用戶體驗(yàn)售担;這就是 Deeper Link
3.實(shí)現(xiàn)的原理?
當(dāng)有安裝app時(shí):用戶先去瀏覽wap頁面署辉,wap頁面觸發(fā)了url跳轉(zhuǎn)族铆,自動喚起了已經(jīng)安裝的app,并且伴隨著url傳遞來了數(shù)據(jù)哭尝,一氣呵成骑素,沒錯(cuò)用戶很自然的從wap上的操作行為,延續(xù)到了app上.
-
當(dāng)沒有安裝app時(shí):需要跨越沙盒傳遞數(shù)據(jù)刚夺,deferred deep link(延遲深度鏈接)
- 1.用戶通過safari瀏覽wap站献丑,wap站寫用戶行為數(shù)據(jù)進(jìn)入cookie.
- 2.用戶通過引導(dǎo)下載app,運(yùn)行app.
- 3.第一次運(yùn)行app侠姑,app內(nèi)靜默的打開一個(gè)純透明safari(讓用戶感覺不出來).
- 4.純透明的safari訪問一個(gè)專門用來靜默取cookie得頁面.
- 5.純透明的safari訪問的取cookie的頁面创橄,取到了正確的cookie數(shù)據(jù).
- 6.純透明的safari將數(shù)據(jù)通過openurl,靜默的回傳給app.
- 7.app拿到瀏覽器數(shù)據(jù)后莽红,銷毀無用的純透明safari.
4.有哪些突出的優(yōu)勢妥畏?
- 用戶體驗(yàn)好
- 不會出現(xiàn)誤傷即匹配出錯(cuò)的問題
5.如何配置來應(yīng)用此技術(shù)?
按照蘋果官方文檔來說安吁,支持通用鏈接非常簡單喲醉蚁,只需要三步
- 1.創(chuàng)建一個(gè)名字叫做apple-app-site-association,包含固定格式的json文件
- 2.將這個(gè)文件上傳到你的服務(wù)器鬼店,可以將這個(gè)文件放到服務(wù)器的根目錄下网棍,也可以放到.well-known這個(gè)子目錄下。
- 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配置氏身,實(shí)際上就是限制哪些路徑可以喚醒a(bǔ)pp,哪些路徑不能喚醒a(bǔ)pp惑畴。使用*配置蛋欣,則整個(gè)網(wǎng)站都可以使用
蘋果驗(yàn)證通用鏈接是否可用的網(wǎng)站:https://search.developer.apple.com/appsearch-validation-tool/
- 2.app id 配置
app IDs 配置,進(jìn)入開發(fā)者網(wǎng)站如贷,找到你自己的bundleId陷虎,可以點(diǎn)擊edit按鈕,開啟associate domains杠袱,如下圖
-
3.項(xiàng)目配置尚猿,在項(xiàng)目的Capablities中開啟Associated domains,如下圖:
 .png
6.配置時(shí)需注意哪些點(diǎn)霞掺?
- apple-app-site-association文件名字必須為apple-app-site-association谊路,不能帶后綴名讹躯,有的電腦設(shè)置的隱藏后綴名菩彬,這點(diǎn)需要注意。
- 配置的paths路徑潮梯,是區(qū)分大小寫的
- 注意domains可以添加多個(gè)骗灶,前綴必須為applinks:,applinks:后為你的服務(wù)器的域名秉馏。
- 快捷驗(yàn)證耙旦,在備忘錄中輸入https://yourdomain.com/apple-app-site-association,長按這個(gè)鏈接萝究,出現(xiàn)上圖提示則配置成功免都。
Alt text
- 服務(wù)器必須要支持https,而且需要支持TLS1.2協(xié)議以上帆竹,不過相信蘋果強(qiáng)制支持https之后绕娘,這個(gè)坑就會慢慢填上了。現(xiàn)在還有很多童鞋的服務(wù)器使用的免費(fèi)的證書栽连,或者證書不被蘋果信任险领,然后就會導(dǎo)致無法下載apple-app-site-association。蘋果支持的https根證書列表(https://support.apple.com/en-us/HT204132)
- 只支持iOS9以上
- 使用charles抓包顯示秒紧,只有初次安裝app時(shí)才會去請求apple-app-site-association文件绢陌,所以測試時(shí)有可能因?yàn)榫W(wǎng)絡(luò)波動導(dǎo)致apple-app-site-association文件獲取失敗。這種情況熔恢,多卸載幾次脐湾,安裝時(shí)使用4G。
- 驗(yàn)證各種配置的還有一個(gè)網(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中實(shí)現(xiàn)上面這個(gè)方法耗啦,當(dāng)使用Universal Links喚醒a(bǔ)pp時(shí)就執(zhí)行這個(gè)方法;接下來就是打開一個(gè)透明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);
}
}
}
當(dāng)透明safari加載完畢后,略微延遲后直接銷毀safari蚀苛,如果在延遲期間在验,openurl返回則判斷,取cookie數(shù)據(jù)成功堵未,回調(diào)成功腋舌,如果超時(shí),就判斷取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 端如何判斷一個(gè)app 是否安裝
- 如何跳轉(zhuǎn)到app store或者安裝的app上
9. 參考文檔?
SupportUniversalLinks
deepLink iOS 應(yīng)用到自己APP 記錄
iOS9 Universal Links踩坑之旅雌芽,移動應(yīng)用之deeplink喚醒a(bǔ)pp
簡單的Mac-Custom-URL-Scheme-demo
deeplink的一點(diǎn)簡單研究