背景
我們?cè)陂_(kāi)發(fā)中經(jīng)常會(huì)遇到從微信类少、從網(wǎng)頁(yè)、從自家App中打開(kāi)另外一個(gè)App的需求封拧,并且要求跳轉(zhuǎn)到指定頁(yè)面志鹃,并繼續(xù)完成后續(xù)業(yè)務(wù)。喚起App三種方案對(duì)比:
1泽西、URL Scheme
a曹铃、配置
b、調(diào)用?
優(yōu)點(diǎn):
十分簡(jiǎn)單捧杉,在plist文件中配置一個(gè)scheme陕见,點(diǎn)擊短信中的scheme或者將scheme輸入到瀏覽器中就可以直接跳到App中。
缺點(diǎn):
當(dāng)手機(jī)上沒(méi)有安裝App時(shí)味抖,短信中點(diǎn)擊scheme會(huì)沒(méi)有反應(yīng)评甜,瀏覽器中會(huì)訪問(wèn)失敗仔涩;而且這種方式不太安全忍坷;對(duì)于喚起后跳轉(zhuǎn)到App指定頁(yè)面的這種方式拓展性不強(qiáng)。(而且在微信和QQ中這種方式是被禁用的)
2熔脂、寫(xiě)一個(gè)網(wǎng)頁(yè)
在短信中點(diǎn)擊鏈接佩研,直接跳轉(zhuǎn)到網(wǎng)頁(yè)(引導(dǎo)下載頁(yè)),在網(wǎng)頁(yè)中判斷是iOS端還是安卓端霞揉,然后自動(dòng)跳轉(zhuǎn)對(duì)應(yīng)的scheme旬薯,如果手機(jī)上安裝了App,則直接跳到App零聚,如果沒(méi)有安裝App袍暴,則停留在當(dāng)前網(wǎng)頁(yè),在網(wǎng)頁(yè)上有一個(gè)去下載的按鈕隶症,點(diǎn)擊按鈕可以去蘋(píng)果商店下載App政模。
在h5頁(yè)面中判斷是否成功喚起:
如果從h5頁(yè)面喚起了App的話,頁(yè)面就會(huì)進(jìn)入后臺(tái)運(yùn)行蚂会,會(huì)觸發(fā)h5頁(yè)面的?visibilitychange?事件淋样。如果觸發(fā)了,則表明頁(yè)面被成功喚起胁住。
3趁猴、Universal Link (通用鏈接) - 最低支持iOS9
現(xiàn)在App都是最低支持iOS9了,可以直接用Universal Link替換URL Scheme了彪见。
優(yōu)點(diǎn):
? ??· 唯一性: 它使用標(biāo)準(zhǔn)的 https 鏈接到你的web站點(diǎn)儡司,所以它不會(huì)被其它的App所聲明。
? ??· 安全: 只有你自己才能上傳文件到你網(wǎng)站的根目錄余指,所以你的網(wǎng)站和你的App之間的關(guān)聯(lián)是安全的捕犬。iOS會(huì)去你的網(wǎng)站上去下載你上傳上去的說(shuō)明文件(這個(gè)說(shuō)明文件聲明了你的App可以打開(kāi)哪些類型的https鏈接)。
? ??· 可變: Universal Links本身是一個(gè) https 鏈接,當(dāng)用戶手機(jī)上沒(méi)有安裝你的App的時(shí)候也能夠工作碉碉。此時(shí)點(diǎn)擊鏈接會(huì)跳轉(zhuǎn)到safari中展示你網(wǎng)頁(yè)柴钻。
? ??· 簡(jiǎn)單: 一個(gè)URL鏈接,可以同時(shí)作用于網(wǎng)站和App。
? ??· 私有: 其它App可以在不需要知道你的App是否安裝了的情況下和你的App相互通信.
一垢粮、Universal Link的基本運(yùn)作流程
App第一次啟動(dòng)贴届、更新版本后第一次啟動(dòng),都會(huì)自動(dòng)下載?apple-app-site-association?配置文件
? ??· 下載 - App向工程里配置的域名發(fā)起Get請(qǐng)求拉取配置好存放在https服務(wù)器上的配置文件
? ??· 注冊(cè) - App將配置文件注冊(cè)給手機(jī)系統(tǒng)
? ??· 命中 - 由任意h5蜡吧、或其他App發(fā)起的跳轉(zhuǎn)url毫蚓,如果命中了配置文件注冊(cè)過(guò)的通用鏈接,就打開(kāi)App
? ??· 沒(méi)命中 - 直接跳轉(zhuǎn)url鏈接對(duì)應(yīng)的h5頁(yè)面
二斩跌、Universal Link配置 - 開(kāi)發(fā)步驟
1绍些、開(kāi)發(fā)者賬號(hào)配置:
打開(kāi)證書(shū)頁(yè)面捞慌,找到Identifiers下App IDs下自己的證書(shū)耀鸦;勾選?Associated Domains?
2、Xcode配置:
在Capabilities選項(xiàng)下打開(kāi)Associated Domains啸澡;在Domains中填入你想支持的域名(存放打開(kāi)App的文件的https服務(wù)器地址袖订,必須?applinks:?開(kāi)頭) 該列表限制為不超過(guò)20到30個(gè)。?
配置完后嗅虏,Xcode中會(huì)自動(dòng)生成一個(gè)?.entitlements?文件洛姑,專門存放Associated Domains的配置信息。 如果你的項(xiàng)目中有多個(gè)環(huán)境每個(gè)環(huán)境的域名不同皮服,你可以拷貝多個(gè).entitlements文件楞艾,每個(gè)環(huán)境對(duì)應(yīng)一個(gè).entitlements。
3龄广、apple-app-site-association文件配置:
配置并上傳配置文件到服務(wù)器中該域名的根目錄下硫眯,可以用GET請(qǐng)求可以獲取到這個(gè)配置文件。需注意的是文件不需要加后綴择同,部分服務(wù)器無(wú)法訪問(wèn)無(wú)后綴的文件, (文件的未壓縮大小不得大于128 KB两入,數(shù)組中字典的順序決定了系統(tǒng)在尋找匹配項(xiàng)時(shí)所遵循的順序)
apple-app-site-association文件名固定,不能修改,不能加后綴; 必須支持https且不能重定向
{
? ? "applinks":{
? ? ? ? "apps":[],
? ? ? ? "details":[
? ? ? ? ? ? {
? ? ? ? ? ? ? ? "appID":”9JXXXXXXNQ.com.XXXX.test",
? ? ? ? ? ? ? ? "paths":["/dgtest/*"] //只要鏈接中包含/dgtest/就可以喚起app
? ? ? ? ? ? }
? ? ? ? ]
? ? }
}
a、配置
appID:組成方式是?teamId + bundle identifier敲才。如上面的 9JXXXXXXNQ就是teamId裹纳。登陸開(kāi)發(fā)者中心,在Account -> Membership里面可以找到Team ID紧武。
paths:設(shè)定你的App支持的路徑列表剃氧,只有這些指定的路徑的鏈接,才能被App所處理阻星。paths是按照順序匹配路徑的朋鞍,所以高優(yōu)先級(jí)路徑要放在前面。
指定網(wǎng)站路徑的規(guī)則:
? ??· 使用 "*" 指定整個(gè)網(wǎng)站
? ??· 包含特定的網(wǎng)址(例如"/wwdc/news/")以指定特定的鏈接
? ??· 附加*到特定的網(wǎng)址(例如"/videos/wwdc/2015/*")以指定網(wǎng)站的一部分
? ??· 除了用于*匹配任何子字符串之外,您還可以?用于匹配任何單個(gè)字符番舆。您可以將兩個(gè)通配符合并在一個(gè)路徑中酝碳,例如"/foo/*/bar/201?/mypage"。
? ??· 如果要指定不應(yīng)作為通用鏈接處理的區(qū)域恨狈,請(qǐng)?jiān)诼窂阶址拈_(kāi)頭添加“ NOT ”(注意有一個(gè)空格?"NOT /wwdc/2010/*")
b疏哗、上傳
上傳文件到HTTPS Web服務(wù)器的根目錄或 .well-known 子目錄。 這是為了蘋(píng)果能獲取到你上傳的文件禾怠。上傳完后,自己先訪問(wèn)一下,看看是否能夠獲取到文件返奉,當(dāng)你在瀏覽器中輸入這個(gè)文件鏈接后,應(yīng)該是直接下載apple-app-site-association配置文件吗氏。
4芽偏、實(shí)現(xiàn)接收方法:
Appdelegate中實(shí)現(xiàn) continueUserActivity: 代理方法,并做打開(kāi)的相應(yīng)處理(不實(shí)現(xiàn)也不影響喚起功能)
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{
? ? NSString *url = [userActivity.webpageURL absoluteString];
? ? url = [url stringByRemovingPercentEncoding];
? ? //進(jìn)行自定義處理
? ? return YES;
}
5弦讽、調(diào)用
["*"]? ? ? ? ? 調(diào)起https://mbankshare.XXXX.cn就可以啟動(dòng)App
["/dgtest/*"]? 調(diào)起https://mbankshare.XXXX.cn/dgtest/*就可以啟動(dòng)App復(fù)制代碼
在任何地方打開(kāi)你的網(wǎng)址污尉,系統(tǒng)命中后會(huì)直接跳轉(zhuǎn)到你的app,沒(méi)有命中會(huì)跳轉(zhuǎn)到對(duì)應(yīng)的網(wǎng)頁(yè)往产;
如果在Safari中打開(kāi)網(wǎng)址被碗,在出現(xiàn)的網(wǎng)頁(yè)上方下滑,可以看到有在”XX”應(yīng)用中打開(kāi)仿村,點(diǎn)擊“打開(kāi)”按鈕直接跳轉(zhuǎn)App锐朴。?
三、拓展
最新官方文檔?偶然間看到蘋(píng)果新的文檔蔼囊,關(guān)聯(lián)文件格式有比較大的改動(dòng)焚志,這里簡(jiǎn)單做個(gè)記錄:
構(gòu)建關(guān)聯(lián)文件后,將其放置在站點(diǎn)的?/.well-known/?目錄下畏鼓。(文檔沒(méi)有提到放在根目錄下酱酬,不知道是否還支持)
從macOS 11和iOS 14開(kāi)始,應(yīng)用程序不再將apple-app-site-association文件請(qǐng)求直接發(fā)送到Web服務(wù)器滴肿。而是將這些請(qǐng)求發(fā)送到專用于關(guān)聯(lián)域的Apple管理的內(nèi)容交付網(wǎng)絡(luò)(CDN)岳悟。
{
? "applinks": {
? ? ? "details": [
? ? ? ? ? {
? ? ? ? ? ? "appIDs": [ "ABCDE12345.com.example.app", "ABCDE12345.com.example.app2" ],
? ? ? ? ? ? "components": [
? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? "/": "/buy/*",
? ? ? ? ? ? ? ? ? "comment": "匹配路徑以 /buy/ 開(kāi)頭的任何URL"
? ? ? ? ? ? ? },
? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? "/": "/help/*",
? ? ? ? ? ? ? ? ? "?": { "articleNumber": "????" },
? ? ? ? ? ? ? ? ? "comment": "匹配路徑以/help/開(kāi)頭的任何URL,該URL有一個(gè)為'articleNumber'的查詢項(xiàng)泼差,值為4個(gè)字符"
? ? ? ? ? ? ? },
? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? "/": "/help/website/*",
? ? ? ? ? ? ? ? ? "exclude": true,
? ? ? ? ? ? ? ? ? "comment": "匹配路徑以 /help/website/ 開(kāi)頭的任何URL贵少,并指示系統(tǒng)不要將其作為通用鏈接打開(kāi)"
? ? ? ? ? ? ? },
? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? "#": "no_universal_links",
? ? ? ? ? ? ? ? ? "exclude": true,
? ? ? ? ? ? ? ? ? "comment": "匹配任何片段等于 no_universal_links 的URL,并指示系統(tǒng)不要將其作為通用鏈接打開(kāi)"
? ? ? ? ? ? ? }
? ? ? ? ? ? ]
? ? ? ? ? }
? ? ? ]
? },
? "webcredentials": {
? ? ? "apps": [ "ABCDE12345.com.example.app" ]
? },
? ? "appclips": {
? ? ? ? "apps": ["ABCED12345.com.example.MyApp.Clip"]
? ? }
}
第一層級(jí)多了這兩個(gè):
Web Credentials?是手機(jī)上的密碼(證書(shū))填充功能
App Clips?是輕應(yīng)用功能
details詞典僅適用于applinks服務(wù)類型堆缘;其他服務(wù)類型不使用它滔灶。的components關(guān)鍵是字典的陣列,其提供模式匹配的URL的組件吼肥。
注意:
? ? · 如果要對(duì)沒(méi)有path的域名進(jìn)行支持(如:www.163.com?)录平, 在json文件的paths中用通配符’*’是不行的麻车,需要在paths數(shù)組中加入’/’進(jìn)行匹配。
? ? · 服務(wù)器的域名地址必須是HTTPS的斗这,并且SSL證書(shū)必須通過(guò)蘋(píng)果信任动猬。蘋(píng)果支持的HTTPS證書(shū)列表。
? ? · 即使頁(yè)面打開(kāi)是404表箭,只要網(wǎng)址格式符合規(guī)則赁咙,也是可以命中的
? ? · App處于運(yùn)行或者后臺(tái)時(shí)點(diǎn)擊分享出去的鏈接然后跳轉(zhuǎn)到應(yīng)用里買呢以及對(duì)應(yīng)的界面,但是App殺死在點(diǎn)擊分享出去的鏈接只是單獨(dú)的喚醒App并沒(méi)有執(zhí)行 continueUserActivity 這個(gè)方法(可能是在啟動(dòng)的時(shí)候做了其他操作免钻,從而影響了在continueUserActivity方法中的處理)
無(wú)法喚起解決方案:
1彼水、當(dāng)我所有配置都配完,發(fā)現(xiàn)無(wú)法喚起极舔,檢查發(fā)現(xiàn)把英文的引號(hào)"打成了中文的引號(hào)“凤覆。
2、改好后再了幾遍確認(rèn)配置無(wú)誤后拆魏,依然還是無(wú)法喚起App盯桦。
于是嘗試了如下方法:
? ? · 關(guān)閉代理;
? ? · 清空safari緩存;
? ? · safari不要開(kāi)啟隱私模式;
? ? · 重啟手機(jī);
? ? · 重新安裝App;
結(jié)果:依然無(wú)法喚起
3、在蘋(píng)果驗(yàn)證網(wǎng)站驗(yàn)證稽揭,一直提示:“XXX" isn't a valid webpage URL. Please check your URL and try again.(即使正常的地址也會(huì)提示這個(gè)俺附,不知道什么情況)
4、繼續(xù)用HTTP狀態(tài)查詢工具(查重定向等)排查問(wèn)題溪掀,發(fā)現(xiàn)http狀態(tài)碼是202。?
最后找后臺(tái)同事溝通了老半天步鉴,最終發(fā)現(xiàn)原來(lái)是我們服務(wù)器加了安全設(shè)備檢測(cè)工具揪胃,對(duì)網(wǎng)絡(luò)進(jìn)行了攔截導(dǎo)致的,蘋(píng)果發(fā)起請(qǐng)求的時(shí)候被判定為非安全氛琢,所以導(dǎo)致被攔截了喊递。所以apple-app-site-association文件下載一直是失敗的,喚起App也就不會(huì)成功了 T.T
參考:
iOS微信授權(quán)登錄+Universal Link(通用鏈接)?
iOS 喚起App之Universal Link(通用鏈接)
如發(fā)現(xiàn)遺漏或者錯(cuò)誤阳似,請(qǐng)?jiān)谙路皆u(píng)論區(qū)留言骚勘。