iOS Universal Links & URL Scheme

最近我們有一個(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


    注冊(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


      Safari 輸入

      彈出提示框,TestUrlScheme 是 app 名字
    • 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加入工程豫缨。


      打開Associated
    • 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)成了。
    Associated Domains

    如有不清晰冲呢,可以再看這個(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 **
    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í)替換就好了简识。

Dictionary
String

另外出現(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(通用鏈接)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末恨搓,一起剝皮案震驚了整個(gè)濱河市院促,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌斧抱,老刑警劉巖常拓,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異辉浦,居然都是意外死亡弄抬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門宪郊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掂恕,“玉大人,你說我怎么就攤上這事弛槐“猛觯” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵乎串,是天一觀的道長店枣。 經(jīng)常有香客問我,道長叹誉,這世上最難降的妖魔是什么艰争? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮桂对,結(jié)果婚禮上甩卓,老公的妹妹穿的比我還像新娘戏锹。我一直安慰自己鸭叙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著然低,像睡著了一般。 火紅的嫁衣襯著肌膚如雪卒煞。 梳的紋絲不亂的頭發(fā)上掸茅,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音弱匪,去河邊找鬼青瀑。 笑死,一個(gè)胖子當(dāng)著我的面吹牛萧诫,可吹牛的內(nèi)容都是我干的斥难。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼帘饶,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼哑诊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起及刻,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤镀裤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后缴饭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體暑劝,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年颗搂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了担猛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡峭火,死狀恐怖毁习,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情卖丸,我是刑警寧澤纺且,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站稍浆,受9級(jí)特大地震影響载碌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜衅枫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一嫁艇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧弦撩,春花似錦步咪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽点晴。三九已至,卻和暖如春悯周,著一層夾襖步出監(jiān)牢的瞬間粒督,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工禽翼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留屠橄,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓闰挡,卻偏偏與公主長得像锐墙,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子解总,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容