-
Safari View Controller is iOS 9 only. You need Xcode 7 (beta 2 currently) to use it
-
React Native 0.6.0 is the minimum I got this working on
You might need to add this to your Info.plist in order for iOS 9 to load your application correctly:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
First, create a new Cocoa touch class in your iOS folder called MySafariViewController.m. You safe yourself some trouble if you do it with Xcode's wizards, as it also adds the file to the list of compiled files.
Here's the implementation:
#import "MySafariViewController.h"
@interface MySafariViewController ()
@end
@implementation MySafariViewController
// Expose this module to the React Native bridge
RCT_EXPORT_MODULE()
RCT_EXPORT_METHOD(presentSafari:(NSString *)url) {
NSLog(@"Presenting with url %@", url);
SFSafariViewController *safariViewController = [[SFSafariViewController alloc]
initWithURL:[NSURL URLWithString:url]
entersReaderIfAvailable:YES];
safariViewController.delegate = self;
dispatch_async(dispatch_get_main_queue(), ^{
UIViewController *rootViewController = [[
[UIApplication sharedApplication] keyWindow] rootViewController];
[rootViewController presentViewController:safariViewController animated:YES completion: nil];
});
}
-(void) safariViewControllerDidFinish:(nonnull SFSafariViewController *)controller {
UIViewController *rootViewController = [
[[UIApplication sharedApplication] keyWindow] rootViewController];
[rootViewController dismissViewControllerAnimated:YES completion:nil];
}
@end
Next, you need a to edit the MySafariViewController.h header file:
#import <UIKit/UIKit.h>
#import <RCTBridge.h>
#import <SafariServices/SafariServices.h>
@interface MySafariViewController : NSObject <RCTBridgeModule, SFSafariViewControllerDelegate>
@end
And that's it! Now you can just call the code from your React Native application like this:
module.exports = React.createClass({
_openSafari(url) {
const {MySafariViewController} = require('NativeModules')
MySafariViewController.presentSafari(url)
},
render() {
return (
<TouchableHighlight onPress={() => this._openSafari("http://google.com")}>
<Text>Click for google</Text>
</TouchableHighlight>
)
}
})
Some possible improvements:
-
entersReaderIfAvailable could be parameterized
-
call a callback after the user closes the view (
RCTResponseSenderBlock
in native code)