URL Scheme與openURL,URLSchemeopenURL
URL Schemes
URL Schemes是蘋果給出的用來跳轉到系統應用或者跳轉到別人的應用的一種機制。同時還可以在應用之間傳資料。
設定一個URL Schemes:選中App工程->Info->URL Types裡添加,可以添加多個。
在Info.plist裡是這樣的:
開啟App的代碼是這樣的:
1 NSURL *url = [NSURL URLWithString:@"testapp://"];2 [[UIApplication sharedApplication] openURL:url];
如果兩個應用有URL Schemes是相同的,後安裝的應用的URL Schemes會把早安裝的應用的URL Schemes覆蓋掉。
在safari中開啟
註冊了URL Schemes的應用,用safari瀏覽器也是可以開啟的。用這個可以來驗證應用是否設定了想要的URL Schemes
方法:直接在safari的地址欄輸入testapp://
, enter就可以開啟了
canOpenURL
canOpenURL
方法判斷能否開啟這個url,然後再用openURL
方法開啟該URL的。這樣可以帶來更好的使用者體驗。
1 if ([[UIApplication sharedApplication] canOpenURL:url]) {2 [[UIApplication sharedApplication] openURL:url];3 }
iOS9的時候蘋果加強了許可權,只有在info.plist檔案中加入了URL Schemes白名單才能使用canOpenURL:
方法來判斷是否能開啟該url。該白名單的上限是50個。
白名單在這添加(圖中是接入FacebookSDK後添加的項):
對應的Info.plist:
使用URL Schems傳遞資料
URL Schemes除了可以用來開啟APP之外,還可以用來在兩個App之間傳遞少量的資料。
1 - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url NS_DEPRECATED_IOS(2_0, 9_0, "Please use application:openURL:options:") __TVOS_PROHIBITED;2 3 - (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;4 5 - (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
url可以這麼寫:testapp://www.abc.com/abc?title=hello&content=helloworld,以上三個方法的url就會接收到後面的參數資訊,這樣就實現了app間的資料傳遞。
以下是這三個回調的區別:
- 3個回調的功能基本一樣,都是在別人通過URL Schemes開啟應用的時候會執行的。
不同之處:
- A回調是在iOS2.0的時候推出的,參數只有
url
。
- B回到是在iOS4.2的時候推出的,參數有
url
sourceApplication
annotation
.
- C回調是iOS9.0的時候推出的,參數有
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 applicationUIKIT_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 propertyUIKIT_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
- 這幾個回調是有優先順序的。C>B>A。也就是說,如果你3個回調都實現了,那麼程式只會執行C回調。其他回調是不會執行的。(當然,iOS9以下只會執行B回調)。
最後,在接入多個sdk的時候,sdk之間可能會重寫openurl方法,可能會導致A把B蓋住了,B的openurl回調再也調用不起來。
舉個例子,項目接入了shareSDK和facebookSDK,就發現facebookSDK的登入回調一直拉不起來。
如何驗證這一點,可以在回調處打斷點,如:
如果根本斷不到,多半就是被別的幹掉了,搜下項目裡還有沒有類似的AppController裡也實現了這個函數,看看別的sdk是怎麼幹掉的,要麼做取捨,要麼花力氣做相容。
整理自(http://www.jianshu.com/p/0811ccd6a65d),與自己趟坑的一些體會。