iOS中使用URL Scheme進行App跳轉的教程
URL Scheme的作用
我們都知道蘋果手機中的APP都有一個沙盒,APP就是一個資訊孤島,相互是不可以進行通訊的。但是iOS的APP可以註冊自己的URL Scheme,URL Scheme是為方便app之間互相呼叫而設計的。我們可以通過系統的OpenURL來開啟該app,並可以傳遞一些引數。
例如:你在Safari裡輸入www.alipay.com,就可以直接開啟你的支付寶app,前提是你的手機裝了支付寶。如果你沒有裝支付寶,應該顯示的是支付寶下載介面,點選會跳到AppStore的支付寶下載介面。
URL Scheme必須能唯一標識一個APP,如果你設定的URL Scheme與別的APP的URL Scheme衝突時,你的APP不一定會被啟動起來。因為當你的APP在安裝的時候,系統裡面已經註冊了你的URL Scheme。
一般情況下,是會呼叫先安裝的app。但是iOS的系統app的URL Scheme肯定是最高的。所以我們定義URL Scheme的時候,儘量避開系統app已經定義過的URL Scheme。
註冊URL Scheme
1.在info.plist裡新增URL types
每一個專案裡面都會有一個info.plist配置檔案。找到info.plist,右鍵選擇Add Row,然後選擇URL types。如圖所示:
2.新增URL Schemes
新增完URL types,點選展開。右鍵選擇Add Row,新增URL Schemes:
3.設定URL Schemes
設定URL Schemes為iOSDevTip
4.設定URL Identifier
URL Identifier是自定義的 URL scheme 的名字,一般採用反轉域名的方法保證該名字的唯一性,比如 com.iOSStrongDemo.www
新增成功啟動提示
為了方便測試,我們在AppDelegate裡面新增一個UIAlertView,當app被成功開啟時,會提出提示:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL*)url
{
// 接受傳過來的引數
NSString *text = [[url host] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"開啟啦"
message:text
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView show];
return YES;
}
Safari啟動自定義的URL Schemes APP
既然已經配置好URL Schemes,那麼我們可以來款速測試一下,我們設定的URL Schemes是否有效。開啟Safari,在位址列裡輸入:iOSDevTip://
果然成功開啟:
也可以在位址列中輸入:iOSDevTip://com.iOSStrongDemo.www。也是可以開啟註冊了URL Schemes的APP的。
通過另一個APP啟動註冊了URL Schemes的APP
NSString *url = @"iOSDevTip://";
// NSString *url = @"iOSDevTip://com.iOSStrongDemo.www";
if ([[UIApplication sharedApplication]
canOpenURL:[NSURL URLWithString:url]])
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
}
else
{
NSLog(@"can not open URL scheme iOSDevTip");
}
開啟註冊iOSDevTip的APP格式為: URL Scheme://URL identifier,直接呼叫URL Scheme也可開啟程式, URL identifier是可選的。
通過註冊的URL Scheme向目標APP傳遞引數
通過URL Scheme啟動APP很簡單就可以做到,但有時候我們想在啟動APP的時候傳遞一些引數,這個時候我們就可以通過URL Scheme自定義URL來傳遞引數了。
昨天我們在AppDelegate呼叫了UIApplicationDelegate的代理方法:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL*)url
{
// 接受傳過來的引數
NSString *text = [[url host] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"開啟啦"
message:text
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView show];
return YES;
}
我們來看看蘋果給這個方法的註釋:
複製程式碼程式碼如下:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url; // Will be deprecated at some point, please replace with application:openURL:sourceApplication:annotation:
這個方法在未來將被廢棄,可以用application:openURL:sourceApplication:annotation:來代替。
URL傳參格式
昨天我們在iOSStrongDemo註冊的URL Scheme還記得是什麼嗎?你應該還有印象的就是iOS開發的ID:iOSDevTip。
假設我們想要傳遞兩個引數分別是名字name和手機號phone,格式如下:
有沒有似曾相識的感覺。我們用get方式請求一個介面是不是就是這樣的。
被啟動的APP處理傳過來的引數
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
NSLog(@"sourceApplication: %@", sourceApplication);
NSLog(@"URL scheme:%@", [url scheme]);
NSLog(@"URL query: %@", [url query]);
// 接受傳過來的引數
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"開啟啦"
message:[url query]
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView show];
return YES;
}
當APP被啟動是,會呼叫代理方法application:openURL:sourceApplication:annotation:。引數URL就是啟動APP的URL,引數sourceApplication就是來源APP的Bundle ID。
我們依然通過Safari來測試,在Safari的位址列中輸入:iOSDevTip://?name=ligang&phone=13888888888
即可開啟APP,看看引數是否傳遞過來:
最後我們看一下列印:
?1 2 3 |
2015-07-15
22:38:25.655 iOSStrongDemo[9983:2894855] sourceApplication: com.apple.mobilesafari
2015-07-15
22:38:28.664 iOSStrongDemo[9983:2894855] URL scheme:iosdevtip
2015-07-15
22:38:28.665 iOSStrongDemo[9983:2894855] URL query: name=ligang&phone=13888888888
|
sourceApplication打印出來是com.apple.mobilesafari,從這裡可以看出來,是從Safari啟動我們的APP的。
我們雖然自定義了URL Scheme,但是我們不能阻止別人通過自定義的URL Scheme來開啟我們的應用。怎麼解決呢?
我們可以指定相應的sourceApplication,也就是相應的Bundle ID,通過Bundle ID來決定是否可以開啟我們的APP:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
NSLog(@"sourceApplication: %@", sourceApplication);
NSLog(@"URL scheme:%@", [url scheme]);
NSLog(@"URL query: %@", [url query]);
if ([sourceApplication isEqualToString:@"com.3Sixty.CallCustomURL"]){
// 接受傳過來的引數
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"開啟啦"
message:[url query]
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView show];
return YES;
}else{
return NO;
}
}
這樣我們就可以通過Bundle ID來決定是否允許開啟我們的APP。