日常咱們作iOS開發,會常常遇到打開其餘的APP的功能。本篇文章講的就是打開別人的APP的一些知識。咱們的目標是:ios
創建一個名爲MyApp的iOS工程。這個MyApp是「個人app」,用來打開另外一個APP的。 添加工程到咱們剛纔建立的OpenApp.xcworkspace。而且在工程的Main.storyboard添加一個button,待會兒咱們會用來寫方法。 git
創建一個名爲WXApp的iOS工程。這個工程是咱們模擬的「微信APP」,是被人打開的那個APP。 爲了區分兩個應用,咱們在Main.storyboard上加一個label,「我是微信App」。 github
好了,準備工做就這麼簡單。瀏覽器
想要打開別人的APP或者讓別人打開咱們的APP,那就須要經過URL Schemes了。bash
URL Schemes是蘋果給出的用來跳轉到系統應用或者跳轉到別人的應用的一種機制。同時還能夠在應用之間傳數據。微信
經過對比網頁連接來理解 iOS 上的 URL Schemes,應該就容易多了。 URL Schemes 有兩個單詞:app
爲了能讓別的App(包括咱們剛纔建立的MyApp)可以打開WXApp,咱們須要爲WXApp添加一個URL Schemes。 步驟:選中WXApp工程->Info->URL Types->點擊「+」->在URL Schemes欄填上 weixin
ui
備註:一個應用是能夠有多個URL Schemes的。你能夠再次點擊「+」來添加一個URL Schemesurl
咱們看看info.plist文件裏面是怎樣的。spa
而後咱們run一下WXApp。(注意一下你run的target是哪一個)
這樣,WXApp就向系統「註冊」了一個URL Schemes,其餘的應用能夠經過openurl:
方法來打開WXApp了。
如今咱們在MyApp裏面打開WXApp。方法很是簡單。 在ViewController裏面添加一個方法
- (IBAction)openWXApp:(UIButton *)sender {
[self demo1];
}
- (void)demo1 {
//建立一個url,這個url就是WXApp的url,記得加上://
NSURL *url = [NSURL URLWithString:@"weixin://"];
//打開url
[[UIApplication sharedApplication] openURL:url];
}
複製代碼
而後run一下MyApp
運行了以後點擊「打開微信」button,會彈出「MyApp」想要打開「WXApp」
提示框,點確認以後就能夠跳轉到WXApp了。
值得一說的是,這個URL Schemes並非惟一的。也就是說,多個應用之間設置的URL Schemes是能夠相同的。 那麼問題來了,假如兩個應用的URL Schemes相同的話,使用
openURL:
方法會打開哪一個應用呢? 樓主親自用手機試了一下。 步驟是:
沒錯,註冊了URL Schemes的應用,用safari瀏覽器也是能夠打開的。我就常常用這個來驗證應用是否設置了我想要的URL Schemes 在safari打開WXApp,直接在safari的地址欄輸入weixin://
,enter就能夠打開了
canOpenURL:
方法先判斷可否打開這個url,而後再用openURL
方法打開該URL的。這樣能夠帶來更好的用戶體驗。由於用戶不必定安裝了WXApp。假如用戶沒有安裝的話點擊「打開微信」button是沒有任何反應的。這時候咱們應該先判斷是否可以打開這個url(也就是判斷用戶有沒有安裝WXApp),沒有安裝的話就給個舒適提示,好比:「U四不四灑,沒安裝WXApp,怎麼打開啊!」。 更重要的是,假如點擊以後沒效果,頗有可能被蘋果拒絕哦。- (IBAction)openWXApp:(UIButton *)sender {
// [self demo1];
[self demo2];
}
//先判斷再打開WXApp
- (void)demo2 {
//建立一個url,這個url就是WXApp的url,記得加上://
NSURL *url = [NSURL URLWithString:@"weixin://"];
//先判斷是否能打開該url
if ([[UIApplication sharedApplication] canOpenURL:url]) {
//打開url
[[UIApplication sharedApplication] openURL:url];
}else {
//給個提示或者作點別的事情
NSLog(@"U四不四灑,沒安裝WXApp,怎麼打開啊!");
}
複製代碼
可是咱們發現用了canOpenURL:
方法以後,並無如咱們想像中打開了WXApp。一看,Xcode控制檯提示:
爲何會這樣呢? 由於iOS9的時候蘋果增強了權限,只有在info.plist文件中加入了URL Schemes白名單才能使用canOpenURL:
方法來判斷是否能打開該url。該白名單的上限是50個。也就是說,你最多隻能使用canOpenURL:
方法判斷50個URL Schemes。固然,日常咱們都用不了那麼多,就算是集成分享功能,50個確定夠了。
備註:只是對
canOpenURL:
方法有限制,openURL:
方法是沒有限制的。
言歸正傳,咱們須要在MyApp的info.plist裏面將weixin
設置爲白名單。 步驟:點擊info.plist->右鍵->Open As->Source Code->添加下面的代碼
<key>LSApplicationQueriesSchemes</key>
<array>
<string>weixin</string>
</array>
複製代碼
這樣就能夠了。
URL Schemes除了能夠用來打開APP以外,還能夠用來在兩個App之間傳遞少許的數據。 在百度上搜索「ios」,會生成一個url,下面來以這個url來大概介紹url的組成。
url爲:https://www.baidu.com/s?ie=UTF-8&wd=ios
ie=UTF-8
和wd=ios
咱們iOS的URL Schemes中也是差很少的。 並且,在openURL
的時候,若是url中帶有參數,只要URL Schemes是正確的,那一樣能夠打開App,並且,後面的參數也會帶到咱們打開的App那裏。 我們作個Demo就一目瞭然了。 在MyApp中,寫個demo3方法,url爲weixin://www.shixueqian.com/abc?title=hello&content=helloworld
- (IBAction)openWXApp:(UIButton *)sender {
// [self demo1];
// [self demo2];
[self demo3];
}
//使用URL Schemes傳遞數據
- (void)demo3 {
//建立一個url,這個url就是WXApp的url,記得加上://
NSURL *url = [NSURL URLWithString:@"weixin://www.shixueqian.com/abc?title=hello&content=helloworld"];
//打開url
[[UIApplication sharedApplication] openURL:url];
}
複製代碼
在WXApp的AppDelegate.m中,實現application: openURL:(NSURL *)url sourceApplication: annotation:
回調
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
NSLog(@"url=====%@ \n sourceApplication=======%@ \n annotation======%@", url, sourceApplication, annotation);
return YES;
}
複製代碼
run了以後,咱們發現,咱們依舊能夠經過點擊openURL:
方法打開WXApp。並且在WXApp被打開的時候,會執行application: openURL:(NSURL *)url sourceApplication: annotation:
回調方法。在這個回調方法中,咱們能夠獲得MyApp傳過來的url等信息。 控制檯打印以下:
完整的url信息都傳過來了,咱們就能夠利用這個url裏面的路徑和參數等信息了,想幹嗎就幹嗎。這就實現了從MyApp向WXApp傳遞數據了。
備註: 蘋果一共給了3個openURL的回調。 分別是:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url NS_DEPRECATED_IOS(2_0, 9_0, "Please use application:openURL:options:") __TVOS_PROHIBITED;
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation NS_DEPRECATED_IOS(4_2, 9_0, "Please use application:openURL:options:") __TVOS_PROHIBITED;
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options NS_AVAILABLE_IOS(9_0); // no equiv. notification. return NO if the application can't open for some reason 複製代碼
爲何會有3個呢?這3個回調又有什麼區別?(爲方面講解,分別設置ABC3個回調)
url
。url
sourceApplication
annotation
.url
options
。options
有下面幾個key// Keys for application:openURL:options:
UIKIT_EXTERN NSString *const UIApplicationOpenURLOptionsSourceApplicationKey NS_AVAILABLE_IOS(9_0); // value is an NSString containing the bundle ID of the originating application
UIKIT_EXTERN NSString *const UIApplicationOpenURLOptionsAnnotationKey NS_AVAILABLE_IOS(9_0); // value is a property-list typed object corresponding to what the originating application passed in UIDocumentInteractionController's annotation property UIKIT_EXTERN NSString *const UIApplicationOpenURLOptionsOpenInPlaceKey NS_AVAILABLE_IOS(9_0); // value is a bool NSNumber, set to YES if the file needs to be copied before use 複製代碼
本篇文章的Demo已經上傳到GitHub上了github.com/shixueqian/…
歡迎觀看個人另外一篇文章,是這篇文章的進階版。 【iOS開發】仿微信分享功能
用通俗的語言,講述動人的代碼故事。