iOS應用間通信:URL Schemes

iOS應用間通信:URL Schemes

拋開越獄不談,URL Schemes幾乎是iOS應用間通信(Inter-app Communication)的唯一選擇(另一種是Air Drop,但主要用于共享大文件)逐工,其重要性毋庸置疑合搅。

更新:Apple在iOS9推出了Universal Links,同樣基于URL,力求統(tǒng)一原生應用和web服務的用戶體驗,可視為URL Schemes的全面升級。當然弧烤,其實現(xiàn)也更為復雜。

A. 什么是URL Schemes

URL用于定位資源蹬敲,譬如網(wǎng)絡資源暇昂。以下面的URL為例:

http://www.example.com/index.php?key1=value1&key2=value2

根據(jù)RFC1808標準莺戒,其包含如下組成部分:

內(nèi)容 角色 作用
http scheme 服務類型。注意急波,http是一種互聯(lián)網(wǎng)協(xié)議从铲,但理論上任意合法字符串都可以充當scheme
www.example.com host 主機域名
index.php path 資源路徑
key1=value1&key2=value2 query 參數(shù)

iOS中,你可以為自己的應用定義URL schemes幔崖,供外界調(diào)用食店。URL格式必須符合標準(即能夠通過NSURL解析)。

總體來說赏寇,URL schemes可劃分為兩類:系統(tǒng)定義&自定義吉嫩。

B. 系統(tǒng)定義的URL Schemes

有些系統(tǒng)應用天生支持URL schemes,例如電話嗅定,郵件自娩,短信,Safari渠退,地圖等忙迁。

/ scheme 范例 效果 備注
電話 tel tel:16812345678 撥打號碼16812345678 電話號碼必傳
郵件 mailto mailto:frank@163.com frank@163.com寫郵件 郵件地址必傳
短信 sms sms:16812345678 編寫發(fā)送給號碼16812345678的短信 電話號碼不是必傳,如不傳碎乃,則僅打開短信應用
Safari http(s) https://www.baidu.com 在Safari中打開網(wǎng)頁 絕大部分http地址都默認使用Safari打開
地圖 http(s) http://maps.apple.com/?q=四川菜 搜索附近的四川菜姊扔。注意,url含有中文時要編碼 地圖的scheme并不是map梅誓,而是一個host為maps.apple.com的http地址

更多關(guān)于系統(tǒng)定義的URL schemes的信息恰梢,詳見官方文檔Apple URL Scheme Reference

C. 調(diào)用URL Scheme

調(diào)用URL scheme其實很簡單梗掰,分為兩步:

  1. 創(chuàng)建URL嵌言;
  2. 要求UIApplication打開它;

注意事項:

  • 調(diào)用特定app及穗,必須事先知道其scheme摧茴;
  • 除scheme外,有些app還要求傳遞額外信息埂陆;信息錯誤苛白,可能無法達到預期效果;
  • 自定義schemes與系統(tǒng)schemes發(fā)生沖突焚虱,默認以后者為準丸氛;
  • 多個app注冊同一個scheme,調(diào)用結(jié)果未知著摔;

打開URL的方法如下:

- (void)openURL:(NSURL *)URL completionHandler:(void (^)(BOOL success))completionHandler;
  • 此方法自iOS10引入,低版本請使用openURL:定续;
  • 回調(diào)completionHandler攜帶一個布爾參數(shù)success谍咆,表示是否成功打開URL禾锤。注意,這里的成功意味著有app響應URL scheme摹察,從而被調(diào)起恩掷;至于URL是否被成功處理,不得而知供嚎;
  • 也就是說黄娘,只要scheme正確,一定會有app被調(diào)起克滴,回調(diào)一定顯示成功逼争;

我們可以嘗試通過Safari調(diào)用某個scheme,具體做法為:在地址欄里輸入targetScheme://劝赔,將targetScheme替換為具體scheme即可誓焦。注意,://不可省略着帽;如果包含中文杂伟,必須編碼。

D. 自定義URL Schemes

自定義URL schemes也可以分為兩步:

  1. 注冊schemes仍翰;
  2. 處理調(diào)用請求赫粥。

D.1 注冊schemes

iOS以URL type為單位管理URL schemes。一個type下可以有多個scheme予借,但一個scheme只對應一個type越平。注冊URL schemes,實際上是注冊URL type蕾羊。

Info.plist中添加鍵值對CFBundleURLTypes喧笔,其對應一個數(shù)組,每個元素都是一個字典龟再,代表一個type书闸。例如:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLIconFile</key>
        <string>iconGinx</string>
        <key>CFBundleURLName</key>
        <string>cn.com.rap.ginx</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>wb2522720237</string>
            <string>wxd3a1541d4423bf8f</string>
            <string>ddyc</string>
            <string>tencent1101352712</string>
            <string>navigationMapBack</string>
        </array>
    </dict>
    <!--其他URL type...-->
<array>

一個URL type字典包含如下鍵值對:

必填 備注
CFBundleURLSchemes 字符串數(shù)組,一個字符串代表一個scheme 一個type下可以有多個scheme
CFBundleURLName type的識別符利凑,必須唯一浆劲。推介使用反向DNS風格的命名方式,如com.myhost.myscheme哀澈。 具體作用不詳
CFBundleURLIconFile type的圖標名稱 圖標用途不詳
CFBundleTypeRole app在type中所扮演的角色 具體作用不詳牌借,使用默認值即可

更多關(guān)于CFBundleURLTypes的信息,詳見Information Property List Key Reference中章節(jié)CFBundleURLTypes的敘述割按。

此外膨报,還可以針對scheme定義啟動圖片。眾所周知,app啟動時會顯示圖片现柠。如果app因為響應某個scheme而啟動院领,可以根據(jù)scheme定義圖片。圖片命名格式如下:

<basename> -<url_scheme> <other_modifiers> .png

更多關(guān)于URL scheme啟動圖片的信息够吩,詳見App Programming Guide for iOS中章節(jié)Displaying a Custom Launch Image When a URL is Opened的敘述比然。

D.2 處理調(diào)用請求

D.2.1 處理邏輯

收到調(diào)用請求后,相應的UIApplication代理方法會被調(diào)用周循,所以這里也是處理邏輯的所在:

// UIApplicationDelegate
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options

注意事項:

  • 此方法自iOS9引入强法,低版本請使用application:openURL:sourceApplication:annotation:
  • url是調(diào)用者傳入的url湾笛,利用NSURL解析饮怯,獲取所需信息;
  • options是字典迄本,通過鍵值對UIApplicationOpenURLOptionsSourceApplicationKey可以獲取調(diào)用者的Bundle ID硕淑;
  • 此方法返回一個布爾值,代表處理成功與否嘉赎;但不影響調(diào)用者的回調(diào)結(jié)果(方法openURL:completionHandler:)置媳。所以這個值的具體作用不詳。

D.2.2 生命周期

被調(diào)用時公条,app可能處于下列狀態(tài)之一:

  1. app未運行拇囊;
  2. app運行中,但在后臺或被掛起靶橱;

D.2.2.1 app未運行時被調(diào)用

app先啟動寥袭,再處理請求,但受到下面方法影響:

// UIApplicationDelegate
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
  • 如果任意方法返回NO关霸,則不處理請求(即方法application:openURL:options:不調(diào)用)传黄;
  • 如果只實現(xiàn)其中一個,則以實現(xiàn)的那個為準队寇;
  • 即使不處理請求膘掰,app仍會啟動,進入前臺佳遣;調(diào)用者收到成功回調(diào)(方法openURL:completionHandler:回調(diào)參數(shù)顯示成功)识埋;

D.2.2.1 app運行中被調(diào)用

app必定會處理請求,進入前臺(即方法application:openURL:options:一定會被調(diào)用)零渐;

E. LSApplicationQueriesSchemes與canOpenURL:

UIApplication方法canOpenURL:可以判斷當前設(shè)備上是否有能夠響應特定URL的應用窒舟。

于是乎,有人利用這個方法過濾大量scheme诵盼,判斷設(shè)備上安裝了哪些應用惠豺。為防止濫用银还,自iOS9,Apple要求這個方法只能檢測特定名單內(nèi)的scheme(當然洁墙,系統(tǒng)定義的scheme不在此列)见剩,開發(fā)者需要通過鍵值對LSApplicationQueriesSchemesInfo.plist中定義這個名單。例如:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>alipay</string>
    <string>tencentweibo</string>
    <string>sinaweibo</string>
    <string>weibo</string>
    <string>mqq</string>
    <string>iosamap</string>
    <string>baidumap</string>
    <string>wechat</string>
    <string>weixin</string>
    <string>sinaweibohd</string>
    <string>weibosdk</string>
    <string>weibosdk2.5</string>
    <string>BestPay</string>
</array>

另外扫俺,還要注意:

  • 方法canOpenURL:的返回值僅表示當前設(shè)備上是否有能夠響應特定URL的應用。并不能反映URL能否被成功處理固翰;
  • 方法openURL:completionHandler:(或openURL:)不受此名單限制狼纬;

更多關(guān)于LSApplicationQueriesSchemes的信息,詳見Information Property List Key Reference中章節(jié)LSApplicationQueriesSchemes的敘述骂际。

參考資料

  1. App Programming Guide for iOS
  2. Apple URL Scheme Reference
  3. Information Property List Key Reference
  4. URL Schemes 使用詳解
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疗琉,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子歉铝,更是在濱河造成了極大的恐慌盈简,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件太示,死亡現(xiàn)場離奇詭異柠贤,居然都是意外死亡,警方通過查閱死者的電腦和手機臼勉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門餐弱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人膏蚓,你說我怎么就攤上這事⊥郧疲” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵幢尚,是天一觀的道長翅楼。 經(jīng)常有香客問我,道長毅臊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任皂林,我火速辦了婚禮,結(jié)果婚禮上础倍,老公的妹妹穿的比我還像新娘。我一直安慰自己沟启,他們只是感情好,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布芽卿。 她就那樣靜靜地躺著胳搞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪肌毅。 梳的紋絲不亂的頭發(fā)上筷转,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天芽腾,我揣著相機與錄音,去河邊找鬼摊滔。 笑死,一個胖子當著我的面吹牛艰躺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播腺兴,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼页响!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起闰蚕,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎没陡,沒想到半個月后索赏,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贴彼,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年融涣,在試婚紗的時候發(fā)現(xiàn)自己被綠了精钮。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡杂拨,死狀恐怖悯衬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情筋粗,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布丽已,位于F島的核電站买决,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏督赤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一躲舌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧羹奉,春花似錦、人聲如沸约计。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽病蛉。三九已至炫加,卻和暖如春瑰煎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背酒甸。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留赋铝,地道東北人插勤。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓革骨,卻偏偏與公主長得像农尖,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子良哲,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

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