URL Scheme与openURL

时间:2024-01-17 23:32:44

URL Schemes

URL Schemes是苹果给出的用来跳转到系统应用或者跳转到别人的应用的一种机制。同时还可以在应用之间传数据。

设置一个URL Schemes:选中App工程->Info->URL Types里添加,可以添加多个。

URL Scheme与openURL

在Info.plist里是这样的:

URL Scheme与openURL

打开App的代码是这样的:

 NSURL *url = [NSURL URLWithString:@"testapp://"];
[[UIApplication sharedApplication] openURL:url];

如果两个应用有URL Schemes是相同的,后安装的应用的URL Schemes会把早安装的应用的URL Schemes覆盖掉。

在safari中打开

注册了URL Schemes的应用,用safari浏览器也是可以打开的。用这个可以来验证应用是否设置了想要的URL Schemes
方法:直接在safari的地址栏输入testapp://, enter就可以打开了

canOpenURL

canOpenURL方法判断能否打开这个url,然后再用openURL方法打开该URL的。这样可以带来更好的用户体验。

 if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}

iOS9的时候苹果加强了权限,只有在info.plist文件中加入了URL Schemes白名单才能使用canOpenURL:方法来判断是否能打开该url。该白名单的上限是50个。

白名单在这添加(图中是接入FacebookSDK后添加的项):

URL Scheme与openURL

对应的Info.plist:

URL Scheme与openURL

使用URL Schems传递数据

URL Schemes除了可以用来打开APP之外,还可以用来在两个App之间传递少量的数据。

 - (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

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 optionsoptions有下面几个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
  • 这几个回调是有优先级的。C>B>A。也就是说,如果你3个回调都实现了,那么程序只会执行C回调。其他回调是不会执行的。(当然,iOS9以下只会执行B回调)。

最后,在接入多个sdk的时候,sdk之间可能会重写openurl方法,可能会导致A把B盖住了,B的openurl回调再也调用不起来。

举个例子,项目接入了shareSDK和facebookSDK,就发现facebookSDK的登录回调一直拉不起来。

如何验证这一点,可以在回调处打断点,如下图:

URL Scheme与openURL

如果根本断不到,多半就是被别的干掉了,搜下项目里还有没有类似的AppController里也实现了这个函数,看看别的sdk是怎么干掉的,要么做取舍,要么花力气做兼容。

整理自(http://www.jianshu.com/p/0811ccd6a65d),与自己趟坑的一些体会。