如何自定義 URL Scheme 進行跳轉

一曲初、URL Scheme 簡介和作用

相信大家都知道 URL酌毡,例如 http://www.reibang.com/ 就是一個URL唾那。

:// 之前的部分就稱為 URL Scheme刘离。

也就是說 http://www.reibang.com/ 的 URL Scheme 就是 http 媳瞪。

更多關于 URL參數(shù)介紹:NSURL簡介

由于蘋果的app都是在沙盒中,相互是不能訪問數(shù)據(jù)的仇味。但是蘋果還是給出了一個可以在app之間跳轉的方法:URL Scheme竹揍。

簡單的說,URL Scheme 就是一個可以讓 app 相互之間可以跳轉的協(xié)議(例如上面的 http)邪铲。

每個app的 URL Scheme 都是不一樣的,如果存在一樣的 URL Scheme无拗,那么系統(tǒng)就會響應先安裝那個app的 URL Scheme带到,因為后安裝的app的 URL Scheme 被覆蓋掉了,是不能被調用的英染。

那么app之間的跳轉有什么作用呢揽惹?我們所使用的每一個app就相當于一個功能,app的跳轉可以使得每個app就像一個功能組件一樣四康,幫助我們完成需要做的事情搪搏,比如三方支付闪金,搜索论颅,導航囱嫩,分享等。

二墨闲、使用URL Scheme 跳轉到系統(tǒng)

要跳轉到別人的app,就要知道別人的app的跳轉協(xié)議是什么鸳碧,需要傳入什么參數(shù),我們常見的跳轉到系統(tǒng)有下面這些:

// 1.打開Mail
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"mailto:frank@wwdcdemo.example.com"]]
// 2.打開電話
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel:1-408-555-5555"]];
// 3.打開SMS
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms:1-408-555-1212"]];

有關系統(tǒng)支持的URL Scheme的詳細信息瞻离,請參閱 Apple URL Scheme ReferenceiOS10如何跳轉到系統(tǒng)設置腾仅。

三、自定義 URL Scheme 進行跳轉

1琐脏、注冊自定義 URL Scheme

如果我們希望別人打開我們的 app(名字叫做 SchemeDemo)攒砖,需要注冊自定義 URL Scheme,通過 info.plist --> URL Types --> item0 --> URL Schemes --> 你的TestScheme 來設置日裙,詳細步驟如下:

  • 1吹艇、點擊工程中的 info.plist 文件,當該文件顯示在如下窗口時昂拂,在列表頂部鼠標選中 Information Property List受神,選擇 +,然后向下滾動彈出的列表并選擇 URL types格侯,類型為 NSArray鼻听。

    添加 URL types

  • 2、點擊 URL types 左邊剪頭打開列表联四,可以看到 Item 0撑碴,一個字典實體。展開 Item 0朝墩,可以看到 URL Identifier醉拓,一個字符串對象。該字符串是你自定義的 URL scheme 的名字收苏。建議采用反轉域名的方法保證該名字的唯一性亿卤,比如 com.yourCompany.yourApp

    設置 URL Identifier

  • 3鹿霸、點擊 Item 0 新增一行排吴,從下拉列表中選擇 URL Schemes,敲擊鍵盤回車鍵完成插入懦鼠。注意 URL Schemes 是一個數(shù)組钻哩,允許應用定義多個 URL schemes屹堰。

    添加 URL Schemes

    URL Schemes 是一個數(shù)組

  • 4、展開 URL Schemes 該數(shù)據(jù)并點擊 Item 0憋槐。你將在這里定義自定義 URL scheme 的名字双藕。只需要名字,不要在后面追加 ://阳仔,比如,如果你輸入 iOSDevApp嘶摊,你的自定義 url 就是 iOSDevApp://叶堆。

    添加 URL Scheme 名字

此時虱颗,整個定義如下圖:


完整定義
2忘渔、從 Safari 中調用自定義 URL Scheme

使用模擬器調用應用的步驟:

  • 在 Xcode 中運行應用

  • 一旦應用被安裝畦粮,自定義 URL scheme 就會被注冊

  • 通過模擬器的硬件菜單中選擇 Home 來關閉應用

  • 啟動 Safari

  • 在瀏覽器地址欄輸入之前定義的 URL scheme (如下)

在 Safari 中調用自定義 URL Scheme
  • 點擊回車宣赔,彈出提示框 (如下)
彈窗提示
  • 點擊 打開 此時 Safari 將會進入后臺儒将,應用會被帶回到前臺钩蚊。

祝賀你剛剛使用自定義 URL scheme 調用了一個 iPhone 應用。

3床估、從另一個應用( NewDemo )中調用( SchemeDemo中的 )自定義 URL Scheme

新建一個應用 NewDemo丐巫,來調用 SchemeDemo 中自定義的 URL scheme 谣拣。

新建應用 NewDemo 只有一個 UIButton赡茸,點擊這個按鈕則會通過應用(SchemeDemo)自定義的 URL scheme 來調用應用(SchemeDemo)占卧。

點擊按鈕通過自定義 URL scheme 進行跳轉

在按鈕點擊方法 clickBtn 中代碼處理 URL 調用:

- (void)clickBtn {
    
    NSString *urlString = @"iOSDevApp://";
    // 若有中文傳輸需要進行轉義
    NSString *customURL = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    // 檢查自定義 URL 是否被定義华蜒,如果定義了叭喜,則使用 shared application 實例來打開 URL
    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:customURL]]) {
        // openURL: 方法啟動應用并將 URL 傳入應用捂蕴,在此過程中啥辨,當前的應用進入后臺
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:customURL]];
        
    } else {
        
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"URL error" message:[NSString stringWithFormat:@"No custom URL defined for %@", customURL] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
        [alert show];
    }
}

如果你的系統(tǒng)版本低于 iOS 9委可,那么已經可以進行調用了着倾,但是如果是在 iOS 9及以后的系統(tǒng)版本中仍會出現(xiàn)無法調用燕少,并在控制臺輸出如下錯誤:

-canOpenURL: failed for URL: "iOSDevApp://" - error: "This app is not allowed to query for scheme iosdevapp"

原因:因為從 iOS 9 開始系統(tǒng)引入了 LSApplicationQueriesSchemes客们,就是白名單。

用意:當前App允許訪問的App有哪些恒傻,需要通信雙方均設置為對方的 scheme盈厘,否則當調用對方App時沸手,系統(tǒng)會告訴你 This app is not allowed to query for scheme

調用者和被調用者均需要設置白名單跳仿,一方想調用捐晶,另一方需要也知道將被你調用 租悄,更為安全。

解決辦法:此時需要在 NewDemo 和 SchemeDemo 中的 info.plist 里面相互設置為白名單(LSApplicationQueriesSchemes)胶哲。詳情如下:This app is not allowed to query for scheme

設置好之后重新運行就可以了:點擊打開就可以跳轉到 SchemeDemo 中了鸯屿。

點擊跳轉提示
4寄摆、通過自定義 URL Scheme 向應用傳遞參數(shù)

有時你需要通過自定義 URL 向應用中傳遞參數(shù)婶恼。讓我們看看該如何完成這個工作柏副。

NSURL 作為從一個應用調用另一個的基礎割择,遵循 RFC 1808 (Relative Uniform Resource Locators) 標準。 因此你所熟悉的基于網頁內容的 URL 格式在這里也適用蕉饼。

在自定義了 URL scheme 的應用中昧港,AppDelegate 必須實現(xiàn)以下方法:

// iOS 9.0前方法
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;

// iOS 9.0后方法
- (BOOL)application:(UIApplication *)app openURL:(nonnull NSURL *)url options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options;

從一個應用傳遞參數(shù)到另一個的訣竅是通過 URL创肥。例如,假設我們使用以下的 URL scheme,想傳遞一個名為 “token”的參數(shù)和一個標識注冊狀態(tài)的標志圈膏,我們可以像這樣創(chuàng)建一個 URL:

// 若有中文傳輸需要進行轉義
NSString *customURL = @"iOSDevTips://?token=123abct&registered=1";

在 web 開發(fā)中稽坤,字符串 ?token=123abct&registered=1 被稱作查詢字符串(query string)糯俗。

在被調用(設置了自定義 URL)的應用的 AppDelegate 中得湘,獲取參數(shù)的代碼如下:

// iOS 9.0前方法
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {

    NSLog(@"Calling Application Bundle ID: %@", sourceApplication);
    NSLog(@"URL scheme: %@", [url scheme]);
    NSLog(@"URL query: %@", [url query]);

    return YES;
}

// iOS 9.0后方法
- (BOOL)application:(UIApplication *)app openURL:(nonnull NSURL *)url options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    
    NSLog(@"options: %@", options);
    NSLog(@"Calling Application Bundle ID: %@", [options objectForKey:@"UIApplicationOpenURLOptionsSourceApplicationKey"]);
    NSLog(@"URL scheme: %@", [url scheme]);
    NSLog(@"URL query: %@", [url query]);
    
    return YES;
}

在 iOS 9.0 之后淘正,以上代碼在應用被調用時的輸出如下:

options: {
    UIApplicationOpenURLOptionsOpenInPlaceKey = 0;
    UIApplicationOpenURLOptionsSourceApplicationKey = "--.NewDemo";
}
Calling Application Bundle ID: --.NewDemo
URL scheme: iOSDevApp
URL query: token=123abct&registered=1

注意 “Calling Application Bundle ID”鸿吆,你可以用這個來確保只有你定義的應用可以與你的應用直接交互。

讓我們改變一下代碼蕉毯,來驗證發(fā)起調用的應用的 Bundle ID 是否合法:

// iOS 9.0前方法
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    
    NSLog(@"Calling Application Bundle ID: %@", sourceApplication);
    NSLog(@"URL scheme: %@", [url scheme]);
    NSLog(@"URL query: %@", [url query]);
    
    // Check the calling application Bundle ID
    if ([sourceApplication isEqualToString:@"--.NewDemo"]) {
        
        return YES;
    }
    
    return NO;
}

// iOS 9.0后方法
- (BOOL)application:(UIApplication *)app openURL:(nonnull NSURL *)url options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {

    NSLog(@"options: %@", options);
    NSLog(@"Calling Application Bundle ID: %@", [options objectForKey:@"UIApplicationOpenURLOptionsSourceApplicationKey"]);
    NSLog(@"URL scheme: %@", [url scheme]);
    NSLog(@"URL query: %@", [url query]);
    
    // Check the calling application Bundle ID
    if ([[options objectForKey:@"UIApplicationOpenURLOptionsSourceApplicationKey"] isEqualToString:@"--.NewDemo"]) {
        
        return YES;
    }
    
    return NO;
}

有一點要特別注意,你不能阻止其他應用通過自定義 URL scheme 調用你的應用抒倚,然而你可以跳過后續(xù)的操作并返回 NO,就像上面的代碼那樣含蓉。也就是說项郊,如果你想阻止其它應用調用你的應用着降,創(chuàng)建一個與眾不同的 URL scheme。盡管這不能保證你的應用不會被調用蓄喇,但至少大大降低了這種可能性。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末刃鳄,一起剝皮案震驚了整個濱河市叔锐,隨后出現(xiàn)的幾起案子见秽,更是在濱河造成了極大的恐慌,老刑警劉巖步责,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件勺择,死亡現(xiàn)場離奇詭異省核,居然都是意外死亡昆码,警方通過查閱死者的電腦和手機赋咽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門脓匿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人米母,你說我怎么就攤上這事铁瞒∥ψ蹋” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵煌珊,是天一觀的道長泌豆。 經常有香客問我践美,道長找岖,這世上最難降的妖魔是什么许布? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任蜜唾,我火速辦了婚禮袁余,結果婚禮上,老公的妹妹穿的比我還像新娘棚饵。我一直安慰自己掩完,他們只是感情好,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布欣硼。 她就那樣靜靜地躺著诈胜,像睡著了一般冯事。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上括授,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天荚虚,我揣著相機與錄音,去河邊找鬼梯澜。 笑死晚伙,一個胖子當著我的面吹牛俭茧,可吹牛的內容都是我干的。 我是一名探鬼主播午磁,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼迅皇,長吁一口氣:“原來是場噩夢啊……” “哼衙熔!你這毒婦竟也來了红氯?” 一聲冷哼從身側響起脖隶,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤产阱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后王暗,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體俗壹,經...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡绷雏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年涎显,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片早歇。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡箭跳,死狀恐怖潭千,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤割捅,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布亿驾,位于F島的核電站莫瞬,受9級特大地震影響郭蕉,放射性物質發(fā)生泄漏。R本人自食惡果不足惜旁振,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望梢薪。 院中可真熱鬧,春花似錦甜攀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至彤敛,卻和暖如春与帆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背墨榄。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工玄糟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人袄秩。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓阵翎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親之剧。 傳聞我的和親對象是個殘疾皇子郭卫,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內容