From f4c286f7ac0665edc3027e952d3b445703918c9c Mon Sep 17 00:00:00 2001 From: SangYeob Bono Yu Date: Fri, 4 Dec 2015 08:05:11 -0800 Subject: [PATCH] Add support for Universal Links Summary: Adds support for [Universal Links](https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/AppSearch/UniversalLinks.html). Closes https://github.com/facebook/react-native/pull/4109 Reviewed By: svcscm Differential Revision: D2658105 Pulled By: nicklockwood fb-gh-sync-id: 7d94564f64cda7d31c79cf8f4c450ed2387057be --- Libraries/LinkingIOS/LinkingIOS.js | 21 +++++++++++++++++---- Libraries/LinkingIOS/RCTLinkingManager.h | 4 ++++ Libraries/LinkingIOS/RCTLinkingManager.m | 17 ++++++++++++++++- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/Libraries/LinkingIOS/LinkingIOS.js b/Libraries/LinkingIOS/LinkingIOS.js index 7ee6ace38..1d186ccbf 100644 --- a/Libraries/LinkingIOS/LinkingIOS.js +++ b/Libraries/LinkingIOS/LinkingIOS.js @@ -43,9 +43,22 @@ var DEVICE_NOTIF_EVENT = 'openURL'; * execution you'll need to add the following lines to you `*AppDelegate.m`: * * ``` - * - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { - * return [RCTLinkingManager application:application openURL:url sourceApplication:sourceApplication annotation:annotation]; + * - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url + * sourceApplication:(NSString *)sourceApplication annotation:(id)annotation + * { + * return [RCTLinkingManager application:application openURL:url + * sourceApplication:sourceApplication annotation:annotation]; * } + * + * // Only if your app is using [Universal Links](https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/AppSearch/UniversalLinks.html). + * - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity + * restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler + * { + * return [RCTLinkingManager application:application + * continueUserActivity:userActivity + * restorationHandler:restorationHandler]; + * } + * * ``` * * And then on your React component you'll be able to listen to the events on @@ -71,7 +84,7 @@ var DEVICE_NOTIF_EVENT = 'openURL'; * LinkingIOS.openURL(url) * ``` * - * If you want to check if any installed app can handle a given URL beforehand you can call + * If you want to check if any installed app can handle a given URL beforehand, call * ``` * LinkingIOS.canOpenURL(url, (supported) => { * if (!supported) { @@ -130,7 +143,7 @@ class LinkingIOS { * Determine whether or not an installed app can handle a given URL. * The callback function will be called with `bool supported` as the only argument * - * NOTE: As of iOS 9, your app needs to provide a `LSApplicationQueriesSchemes` key + * NOTE: As of iOS 9, your app needs to provide the `LSApplicationQueriesSchemes` key * inside `Info.plist`. */ static canOpenURL(url: string, callback: Function) { diff --git a/Libraries/LinkingIOS/RCTLinkingManager.h b/Libraries/LinkingIOS/RCTLinkingManager.h index caa3aa2a3..092ca990b 100644 --- a/Libraries/LinkingIOS/RCTLinkingManager.h +++ b/Libraries/LinkingIOS/RCTLinkingManager.h @@ -18,4 +18,8 @@ sourceApplication:(NSString *)sourceApplication annotation:(id)annotation; ++ (BOOL)application:(UIApplication *)application +continueUserActivity:(NSUserActivity *)userActivity + restorationHandler:(void (^)(NSArray *))restorationHandler; + @end diff --git a/Libraries/LinkingIOS/RCTLinkingManager.m b/Libraries/LinkingIOS/RCTLinkingManager.m index 96c01ca2c..749d2c27a 100644 --- a/Libraries/LinkingIOS/RCTLinkingManager.m +++ b/Libraries/LinkingIOS/RCTLinkingManager.m @@ -54,6 +54,19 @@ RCT_EXPORT_MODULE() return YES; } ++ (BOOL)application:(UIApplication *)application +continueUserActivity:(NSUserActivity *)userActivity + restorationHandler:(void (^)(NSArray *))restorationHandler +{ + if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { + NSDictionary *payload = @{@"url": userActivity.webpageURL.absoluteString}; + [[NSNotificationCenter defaultCenter] postNotificationName:RCTOpenURLNotification + object:self + userInfo:payload]; + } + return YES; +} + - (void)handleOpenURLNotification:(NSNotification *)notification { [_bridge.eventDispatcher sendDeviceEventWithName:@"openURL" @@ -62,6 +75,7 @@ RCT_EXPORT_MODULE() RCT_EXPORT_METHOD(openURL:(NSURL *)URL) { + // TODO: we should really return success/failure via a callback here // Doesn't really matter what thread we call this on since it exits the app [RCTSharedApplication() openURL:URL]; } @@ -72,7 +86,8 @@ RCT_EXPORT_METHOD(canOpenURL:(NSURL *)URL if (RCTRunningInAppExtension()) { // Technically Today widgets can open urls, but supporting that would require // a reference to the NSExtensionContext - callback(@[@(NO)]); + callback(@[@NO]); + return; } // This can be expensive, so we deliberately don't call on main thread