最近我們有一個(gè) DeepLink 的需求 用的是 Branch, 在這個(gè)過程中自然會(huì)涉及到 Universal Links 和 Custom URL Schem,在此進(jìn)行筆記下郑现,也把在用 Branch 中遇到的問題分享下。
// Respond to URI scheme links
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
// 我們需要的判斷跳轉(zhuǎn)
return YES;
}
// Respond to Universal Links
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
// 我們需要的判斷跳轉(zhuǎn)
return YES;
}
然后從下面四個(gè)點(diǎn)來了解下這塊:
- Universal Links 和 URL Schem 基本概念的了解
- Universal Links 和 URL Schem 的用法
- Universal Links 和 URL Schem 需要的注意點(diǎn)
- Branch 使用中遇到的問題
一惶我、基本了解
- URL Scheme
URL Scheme 是為方便app之間互相調(diào)用而設(shè)計(jì)的,注冊(cè)自己獨(dú)一的URL Scheme博投,然后進(jìn)行交互绸贡。我們可以通過系統(tǒng)的OpenURL來打開該app,也可以直接通過 Safari 直接打開該 app毅哗,并可以傳遞參數(shù)內(nèi)容听怕。
- Universal Links
iOS 9 之后,蘋果推出的通用鏈接:一種能夠方便的通過傳統(tǒng) HTTP 鏈接來啟動(dòng) APP, 使用相同的網(wǎng)址打開網(wǎng)站和 APP虑绵。
推出它尿瞭,肯定有其優(yōu)點(diǎn): - 唯一性: 不像自定義的scheme,因?yàn)樗褂脴?biāo)準(zhǔn)的http/https鏈接到你的web站點(diǎn),所以它不會(huì)被其它的app所聲明.另外,Custom URL scheme 因?yàn)槭亲远x的協(xié)議,所以在沒有安裝 app 的情況下是無法直接打開的翅睛,而 universal links 本身是一個(gè) HTTP/HTTPS 鏈接声搁,所以有更好的兼容性
- 安全:當(dāng)用戶的手機(jī)上安裝了你的app,那么iOS將去你的網(wǎng)站上去下載你上傳上去的說明文件(這個(gè)說明文件聲明了你的app可以打開哪些類型的http鏈接).因?yàn)橹挥心阕约翰拍苌蟼魑募侥憔W(wǎng)站的根目錄,所以你的網(wǎng)站和你的app之間的關(guān)聯(lián)是安全的.
- 可變:當(dāng)用戶手機(jī)上沒有安裝你的app的時(shí)候,Universal Links也能夠工作.如果你愿意,在沒有安裝你的app的時(shí)候,用戶點(diǎn)擊鏈接,會(huì)在safari中展示你網(wǎng)站的內(nèi)容.
- 簡(jiǎn)單:一個(gè)URL鏈接,可以同時(shí)作用于網(wǎng)站和app
- 私有 其它app可以在不需要知道你的app是否安裝了的情況下和你的app相互通信.
二、用法
兩者代碼里面其實(shí)沒什么區(qū)別捕发,主要是配置的去唄
2-1疏旨、URL Scheme
-
2-1-1、注冊(cè)設(shè)置 URL Scheme
2-1-2扎酷、AppDelegate 設(shè)置
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL*)url {
// 接受傳過來的參數(shù)
NSLog(@"url Scheme === %@\n url Host === %@",url.scheme,url.host);
// url Scheme === testyang url Host === testContent
return YES;
}
- 2-1-3檐涝、打開
-
Safari
App 之間
在另一個(gè) App 中的 info Plist 中添加白名單 Url
-
<key>LSApplicationQueriesSchemes</key>
<array>
<!-- 設(shè)置我們?cè)O(shè)定的法挨,如我們需要的URL Scheme 白名單-->
<string>testYang</string>
</array>
在另一個(gè) APP 中 添加打開的 代碼
NSString *url = @"testYang://testContent";
// NSString *url = @"testYang://com.testYang.www&testContent";
if ([[UIApplication sharedApplication]
canOpenURL:[NSURL URLWithString:url]]) {
// iOS 10 以上用這個(gè)方法谁榜,iOS 10 以下直接用 openURL 就 OK 了
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url] options:@{UIApplicationOpenURLOptionUniversalLinksOnly : @NO} completionHandler:^(BOOL success) {
NSLog(@"success");
}];
}
注意:APP URL格式為: URL Scheme://URL identifier,直接調(diào)用URL Scheme也可打開程序, URL identifier是可選的凡纳。
2-2窃植、Universal Links
- 2-2-1、創(chuàng)建一個(gè)json 格式的apple-app-site-association
{
"applinks": {
"apps": [],
"details": [
{
"appID": "9JA89QQLNQ.com.apple.wwdc",
"paths": [ "/wwdc/news/", "/videos/wwdc/2015/*"]
},
{
"appID": "ABCD1234.com.apple.wwdc",
"paths": [ "*" ]
}
]
}
}
* “appID”組成部分:TeamID + BundleId TeamID
* BundleId 一定要和 APP 的 BundleId 一致惫企。
* apple-app-site-association 文件不能帶后綴
* apple-app-site-association 文件需要上傳到網(wǎng)站根目錄
* 每一個(gè)代表著應(yīng)用的 字典,必須包含一個(gè) appID 和 paths, appID 是teamID 和 bundleID,paths 是一個(gè)字符串的數(shù)組 **明確著應(yīng)用支持的通用鏈接和應(yīng)用程序不支持的通用連接內(nèi)容**
Note: Don’t append .json to the apple-app-site-association
filename. (文件不要接 .json)
-
2-2-2撕瞧、上傳 apple-app-site-association 到服務(wù)器下
- 注意是上傳到web server根目錄下
- paths 路徑是大小寫敏感的
- paths 內(nèi)容可明確哪些通用鏈接需要被處理,哪些不需要
- NOT 使用:為了明確指出不被處理的鏈接,可增加 “NOT”在鏈接前面
例 如 "paths":[ "/wwdc/news/"
,"NOT /videos/wwdc/2015/*"
,"/videos/wwdc/201?/*"]
- 可以使用 星號(hào)
*
明確所有的網(wǎng)頁, 也可以使用一個(gè)明確的的 URL,例如/wwdc/news/6
, 也可以追加 星號(hào)到你的 URL ,例如/videos/wwdc/2015/*
也可以使用 星號(hào)
*
來匹配任何字符,使用?
來匹配一個(gè)字符,可以在路徑 中使用這種混搭的形式, 例如/foo/*/bar/201?/mypage
-
2-2-3、App 內(nèi)的處理
-
2-2-3-1狞尔、在targets->Capabilities->Associated Domains中打開Associated丛版,然后系統(tǒng)會(huì)自動(dòng)幫你寫入.entitlements文件,所以不需要自己去手動(dòng)加偏序。需要注意的是页畦,有人遇到過.entitlements文件沒有被加入工程的,這也會(huì)產(chǎn)生問題研儒,需要手動(dòng)把.entitlements加入工程豫缨。
- 2-2-3-2、代碼內(nèi)的處理 AppDelegate 中
-
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
// 我們需要的判斷跳轉(zhuǎn)
return YES;
}
- 2-2-3-4端朵、在 證書中心的處理
進(jìn)入蘋果Apple Developer --- Member Center - Certificates, Identifiers & Profiles – Identifiers - App IDs –Edit 然后開啟打鉤 Associated Domains 后保存好芭,但此處我這邊自動(dòng)成了。
如有不清晰冲呢,可以再看這個(gè)翻譯iOS Universal Links(通用鏈接)還是很仔細(xì)的舍败。
三、注意點(diǎn)
- URL Scheme
- URL identifier 的唯一性
- iOS9 之后的白名單
- iOS 10 之后的 OpenURL 的被棄用
- Universal Links
- 域名可通過 SSL 訪問 (需要有效的證書)
- 支持上傳一個(gè) JSON 文件到域名(
apple-app-site-association
) - iPhone 至少 iOS 9.2 以上
- 至少 Xcode 7 以上
- 需要真機(jī)測(cè)試, 模擬器不支持通用鏈接
- web server 需要支持 https,客戶端需要通告 https 訪問,并且不支持任何重定向
總的說來敬拓,URL Scheme慢慢會(huì)退出舞臺(tái)邻薯,然后是Universal Links 登上臺(tái)面的時(shí)候。PS: 蘋果驗(yàn)證Universal Links URL 是否正確的網(wǎng)址乘凸。
四厕诡、Branch DeepLink 使用中遇到的問題
作為國外常用的 Branch,國內(nèi)目前基本應(yīng)該不太用的营勤,整體說來其文檔相對(duì)來說灵嫌,還是很清晰的,只是之前一直有兩點(diǎn)困擾我的:
- 如何自定義類型做判斷跳轉(zhuǎn)
一直跳轉(zhuǎn)不成功葛作,設(shè)置好URL 醒第,始終從Web 頁面跳轉(zhuǎn)不到 APP, 只往AppStore 走
1、如何自定義類型做判斷跳轉(zhuǎn)进鸠,因?yàn)樗煌谙到y(tǒng)的稠曼,直接在
openURL
中做判斷,而是先要用其SDK 提供的方法客年。
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
[[Branch getInstance] handleDeepLink:url];
return YES;
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
BOOL handledByBranch = [[Branch getInstance] continueUserActivity:userActivity];
return handledByBranch;
}
但這是第一層霞幅,以前我們判斷就是拿到這個(gè) url 就是直接去判斷,然后跳轉(zhuǎn)到我們想走的跳轉(zhuǎn)路線量瓜,但是此處呢司恳?
[branch initSessionWithLaunchOptions:launchOptions andRegisterDeepLinkHandler:^(NSDictionary *params, NSError *error) {
if (!error && params) {
NSLog(@"params: %@", params.description);
if ([params[@"+clicked_branch_link"] boolValue]) { // 此處代表是 branch_link 點(diǎn)擊進(jìn)入的情況
[DeepLinkManager branchDeepLinkWithParams:params];
}
}
}];
- 2、一直跳轉(zhuǎn)不成功绍傲,設(shè)置好URL 扔傅,始終從Web 頁面跳轉(zhuǎn)不到 APP, 只往 AppStore 走耍共。
注意 Branch 文檔中的 Link Domain 設(shè)置 Associated Domains 錯(cuò)誤啦。
而且通過 branch 的測(cè)試 URL 是滿足條件的 UNIVERSAL LINKS VALIDATOR猎塞。但是在蘋果驗(yàn)證Universal Links URL 是否正確的網(wǎng)址上卻是錯(cuò)誤的:
**cannot fetch app site association **
這就尷尬了试读,branch 處是OK的,apple 提示Universal Links是錯(cuò)誤的荠耽。但同時(shí)也說明 URL Scheme 設(shè)置是對(duì)的钩骇,否則會(huì)單單直接報(bào)出一個(gè) “Error: cannot fetch app site association ” 的錯(cuò)誤。
所以說铝量,此時(shí)的問題又回歸到 Universal Links 沒設(shè)置對(duì)的原因倘屹,沒能正確上傳好app site association,但是此處使用的是 Branch慢叨, 這個(gè)設(shè)置 Universal Links 就是按 Branch 流程 上面走的纽匙,這樣就略顯尷尬啦,一下子原因找不到拍谐,卡了好久哄辣。
解決步驟1: 到 https://domian.com/apple-app-site-association
看是否正確,當(dāng)然用 Branch 的話是https://domian.app.link/apple-app-site-association
, 結(jié)果發(fā)現(xiàn)這是存在的赠尾,但是內(nèi)容有點(diǎn)不一樣 path
"paths": [
"NOT /e/*",
"*",
"/"
]
然后我對(duì)比了下經(jīng)典的例子收集 list-of-universal-link力穗,繼續(xù)尋找中...
解決步驟2: 直接向 branch 郵箱求助,那邊的工作人員會(huì)給出很詳細(xì)的解答步驟气嫁,第一次沒有解決当窗,現(xiàn)在等待第二次郵件回復(fù)...
解決步驟3: 硬是不行,再重新弄一個(gè)賬號(hào)嘗試寸宵,對(duì)比過程是否有遺漏的東東...
PS: 最終解決:
通過郵件得知崖面,蘋果那邊的那個(gè)驗(yàn)證沒有通過其實(shí)也是OK的, 所以那里可以忽略。
只是之前設(shè)置的時(shí)候梯影,設(shè)置錯(cuò)誤了..
注意 branch_key 直接設(shè)置巫员,注意 test 和 live 的區(qū)別,但是其實(shí)可以直接 不用 dictionary, 而用 string, 因?yàn)槲視簳r(shí)設(shè)置成 Debug 狀態(tài)下有時(shí)是無效的甲棍,所以直接用string ,到時(shí)替換就好了简识。
另外出現(xiàn)這個(gè)問題也可以看看 Stack Overflow 的回答:iOS9: Universal Links does not work。
話說起來這也是一個(gè)自己熟悉陌生英文文檔的過程感猛,可以多來幾次七扰,這一兩天全是英文文檔感覺英語都提高了,??陪白,只是希望下次效率可以更高一些颈走。說白了,所有問題都是文檔沒弄清晰的原因咱士。
PS : 再次補(bǔ)充:
有些情況下立由,在 FaceBook轧钓、 QQ、微博 用的是本身的瀏覽器锐膜,都有其限制的毕箍,此時(shí)我們直接用 DeepView , 方能解決,否則會(huì)一直跳轉(zhuǎn)到 AppStore 去的枣耀。
五霉晕、總結(jié)
其實(shí)總的來說庭再,想了解更詳細(xì)的直接看蘋果官方文檔就OK 了捞奕。
往往出錯(cuò)是在看文檔的時(shí)候忽略一些細(xì)節(jié)!明顯是在就是翻譯文檔拄轻,??颅围,但還翻譯錯(cuò)了,或者說理解錯(cuò)了......
備注:
URL Scheme步驟詳解
Using URL Schemes to Communicate with Apps
Support Universal Links
ios-branch-deep-linking
iOS 9 by Tutorials 筆記(三)
Deferred Deep Linking in iOS
iOS Universal Links(通用鏈接)