一個App與另一個App之間的互動,添加了自己的一些理解
URL Scheme 是什麼?
iOS有個特性就是應用將其自身”繫結”到一個自定義 URL scheme 上,該 scheme用於從瀏覽器或其他應用中啟動本應用。常見的分享到第三方之間的跳轉都是基於Scheme的。
通過對比網頁連結來理解iOS 上的 URL Schemes,應該就容易多了。
- URL,我們都很清楚,http://www.apple.com就是個URL,我們也叫它連結或網址;
- Schemes,表示的是一個 URL 中的一個位置——最初始的位置,即 ://之前的那段字元。比如 http://www.apple.com這個網址的Schemes是 http。
根據我們上面對URL Schemes的使用,我們可以很輕易地理解,在以本地應用為主的
你可以完全按照理解一個網頁的 URL ——也就是它的網址——的方式來理解一個 iOS 應用的 URL,拿蘋果的網站和 iOS 上的微信來做個簡單對比:
關於基礎概念性的就講這麼多
專案中關鍵的配置
在專案Info的Url Type中配置(被喚起端)
- 說明
- URL identifier只是一個標示符,隨意填寫,建議寫成:com.*.*反轉域名的方法保證該名字的唯一性。
- URL Scheme就是你用來通訊的命令字首,用來定位一個應用。
在Plist檔案中配置
- 注意:URL Schemes 是一個數組,允許應用定義多個 URL schemes。
接收到喚起如何處理
在代理方法- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation中判斷喚起的來源source app,根據Url所攜帶的引數進行不同的操作。比如跳轉到制定的頁面,相關的邏輯處理等等.
-(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]);// Customer Codereturn YES;}
以上配置是在被喚起應用中配置的。
喚起端
一般情況下,喚起端可以直接呼叫appDelegate的代理方法去喚醒其他應用。
-(void)awakeOtherApp {NSString*customURL = @"otherApp://";if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:customURL]]){[[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];}}
- 這裡需要注意一下在iOS9以後,喚起端需要配置一下
LSApplicationQueriesSchemes.iOS9之後需要,iOS9之後提高了app的安全性,需要給出一個類似白名單的東西,在白名單裡面的才能開啟app。不然報錯: -canOpenURL: failed for URL: “OpenAppTest://mark?id=007” – error: “This app is not allowed to query for scheme OpenAppTest”
1.新建一個app1,在Info.plist檔案的資訊屬性列表裡新建一組,型別是URL types 設定如下
這裡最關鍵的部分在於URL Schemes數組裡的Item 0,後面的填寫的字串就是你用來通訊的命令字首“achao”,URL identifier只是一個標示符,隨意填寫 然後再AppDelegate裡處理過載下面的回撥方法
-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
if ([[url scheme] isEqualToString:@"achao"])
{
NSLog(@"%@",url);
}
return YES;
}
可以看見[url scheme]這個命令是為了拿到url的scheme,就是命令字首“achao” 2.新建app2,這個app什麼都不用操作,只需要去喚醒app1即可,於是我們在viewDidLoad裡寫上這一句[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"achao://hello"]];
"achao"就是app1裡的url scheme,我叫它命令字首(我懷疑apple的應用程式裝上過後有個像通知中心一樣的應用程式來統一管理,而每個應用程式的url scheme都會在那裡被記錄,以供其他app來呼叫該app,至於url scheme屬於哪個應用程式,當然是和app的Bundle identifier相關的),格式採用“字首://..." 3.我們關閉app1,app2,然後再啟動app2,發現app2啟動過後喚醒了app1,並且成功跳轉;我們再關閉app1,app2,然後我們開啟app1進行監測,發現app1被啟動後,進入了,這就實現了兩個app之間的喚醒和通訊 4.當然這時候你可能才想到,那不是很多應用程式都會被其他垃圾程式呼叫了,查詢資料過後,原來還有後續 我們過載這個方法-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
if ([sourceApplication isEqualToString:@"AC.achao.com"])
{
NSLog(@"%@", sourceApplication); //來源於哪個app(Bundle identifier)
NSLog(@"scheme:%@", [url scheme]); //url scheme
NSLog(@"query: %@", [url query]); //查詢串 用“?...”格式訪問
return YES;
}
else
return NO;
}
這就滿足我們的需求了,我們可以通過sourceApplication來判斷來自哪個app以決定要不要喚醒自己的app,也可以通過[url query]來獲得查詢串,這個時候我們需要更改app2的訪問方式才能獲得這個引數[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"achao://hello?name=achao-AC"]];
我們也可以直接在safari離輸入"achao://hello?name=achao-AC"來訪問我們的app1,這個時候sourceApplication就是@"com.apple.mobilesafari"
總結:類似下面的方法[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.baidu.com"]];
[[UIApplicationsharedApplication] openURL:[NSURLURLWithString:@"sms://158********"]];
[[UIApplicationsharedApplication] openURL:[NSURLURLWithString:@"tel://158********"]];
[[UIApplicationsharedApplication] openURL:[NSURLURLWithString:@"mailto://362****@qq.com"]];
我們用過很多,估計也是程式內部設定了類似的url scheme來供其他應用程式操作的
注意事項通過上面的方法可以喚醒其他的應用,簡單總結下一些注意事項。
- URL Scheme 其實就是一個app應用的唯一標誌。通過它來確定開啟那個應用。
- 一定要分清哪些配置在哪方配置,被喚醒與喚醒。
- iOS9之後需要在喚起端加入LSApplicationQueriesSchemes千萬不能忘。
- 還有一個問題還沒解決,如何再次回到喚醒應用的介面。這個需要參考下官方的XCallbackURL。聽說有些複雜,有空再看看。