diff --git a/README.md b/README.md index 9f9f214..d429d0e 100644 --- a/README.md +++ b/README.md @@ -44,13 +44,13 @@ SafariView.show({ ``` ### URL Change Notifications -There isn't an API for retrieving URL changes provided by SFSafariViewController or its delegate in iOS, so there's no way to know where the user is navigating to. However, it is possible to get a notification when the Safari View navigates to an URL scheme specified by your app (e.g. `your-app-name://`). This is especially useful for implementing callback oriented flows such as in OAuth2 / OpenID Connect. +There isn't an API for retrieving URL changes provided by SFSafariViewController or its delegate in iOS, so there's no way to know where the user is navigating to. However, it is possible to get a notification when the Safari View navigates to an URL scheme specified by your app (e.g. `your-app-name://`). This is especially useful for implementing callback oriented flows such as in OAuth2 / OpenID Connect. To get URL notifications for your URL scheme you'll need to: 1. Register an [URL scheme](https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html#//apple_ref/doc/uid/TP40007072-CH6-SW10) in your Xcode Project 2. Make sure you've set up [Linking](https://facebook.github.io/react-native/docs/linking.html) in your react-native project. 3. Listen for URL changes in your react-native code (i.e. `Linking.addEventListener('url', eventHandler)`); - + ## Example Using Safari View in your app will usually look like this: @@ -100,14 +100,16 @@ __safariOptions__ - `tintColor` - A `String` containing a hex, rgba or rgba color to use for the browser controls - `barTintColor` - A `String` containing a hex, rgba or rgba color to use for the background of the browser controls (only available on iOS 10 and higher) - `fromBottom` - A 'Boolean' indicating to open the Safari View from the bottom +- `preferNative` - A 'Boolean' indicating whether to try to open universal links in the native app, before falling back to opening in Safari View __Examples__ ```js SafariView.show({ url: "http://facebook.github.io/react/blog/2015/03/26/introducing-react-native.html", - readerMode: true // optional, - tintColor: "#000" // optional - barTintColor: "#fff" // optional + readerMode: true, // optional, + tintColor: "#000", // optional + barTintColor: "#fff", // optional + preferNative: false, // optional }); ``` diff --git a/SafariViewManager.m b/SafariViewManager.m index b606e2d..cc7597b 100644 --- a/SafariViewManager.m +++ b/SafariViewManager.m @@ -45,6 +45,7 @@ - (void)stopObserving UIColor *tintColorString = args[@"tintColor"]; UIColor *barTintColorString = args[@"barTintColor"]; BOOL fromBottom = [args[@"fromBottom"] boolValue]; + BOOL preferNative = [args[@"preferNative"] boolValue] ; // Initialize the Safari View _safariView = [[SFSafariViewController alloc] initWithURL:url entersReaderIfAvailable:readerMode]; @@ -73,17 +74,22 @@ - (void)stopObserving _safariView.modalPresentationStyle = UIModalPresentationOverFullScreen; } - // get the view controller closest to the foreground - UIViewController *ctrl = RCTPresentedViewController(); - - // Display the Safari View - [ctrl presentViewController:_safariView animated:YES completion:nil]; - - if (hasListeners) { - [self sendEventWithName:@"SafariViewOnShow" body:nil]; + if (!preferNative) { + [self openInSafariView]; + resolve(@YES); + return; } - resolve(@YES); + [[UIApplication sharedApplication] openURL:url + options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @YES} + completionHandler:^(BOOL success) { + if (!success) { + [self openInSafariView]; + } + + resolve(@YES); + } + ]; } RCT_EXPORT_METHOD(isAvailable:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) @@ -101,6 +107,19 @@ - (void)stopObserving [_safariView dismissViewControllerAnimated:true completion:nil]; } +-(void)openInSafariView +{ + // get the view controller closest to the foreground + UIViewController *ctrl = RCTPresentedViewController(); + + // Display the Safari View + [ctrl presentViewController:_safariView animated:YES completion:nil]; + + if (hasListeners) { + [self sendEventWithName:@"SafariViewOnShow" body:nil]; + } +} + -(void)safariViewControllerDidFinish:(nonnull SFSafariViewController *)controller { _safariView = nil;