The RN doco and other examples show how to launch a React-Native view from a native iOS view controller, but not the other way around. Can someone explain how I can do this
An update to this answer with Swift 5. Thanks to
https://github.com/facebook/react-native/issues/1148#issuecomment-102008892
https://stackoverflow.com/a/46007680/7325179 - answer by MStrapko
https://codersera.com/blog/react-native-bridge-for-ios/?unapproved=2851&moderation-hash=77e42524b246d2fda0f763a496156db5#comment-2851 - an elaborate explanation and tutorial by William Dawson
Getting into the Solution:
In AppDelegate.swift
import Foundation
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var bridge: RCTBridge!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let jsCodeLocation: URL
jsCodeLocation = RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index.js", fallbackResource:nil)
let rootView = RCTRootView(bundleURL: jsCodeLocation, moduleName: "RNModuleName", initialProperties: nil, launchOptions: launchOptions)
self.window = UIWindow(frame: UIScreen.main.bounds)
let reactNativeViewController = UIViewController()
reactNativeViewController.view = rootView
let reactNavigationController = UINavigationController(rootViewController: reactNativeViewController)
self.window?.rootViewController = reactNavigationController
self.window?.makeKeyAndVisible()
return true
}
// func goToReactNative() {
// window?.rootViewController?.dismiss(animated: true)
// }
func goNativeStoryboard() {
DispatchQueue.main.async {
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController()
if let vc = vc {
(self.window?.rootViewController as? UINavigationController)?.pushViewController(vc, animated: true)
}
}
}
}
YourViewController.swift
Your regular code
YourApp-Bridging-Header. Please note there are some extra headers as well, that you might not need.
#import "React/RCTBridgeModule.h"
#import "React/RCTBridge.h"
#import "React/RCTEventDispatcher.h"
#import "React/RCTRootView.h"
#import "React/RCTUtils.h"
#import "React/RCTConvert.h"
#import "React/RCTBundleURLProvider.h"
#import "RCTViewManager.h"
#import "React/RCTEventEmitter.h"
ConnectingFile.swift
@objc(Connect)
class Connect: NSObject {
@objc func goToNative() -> Void {
DispatchQueue.main.async {
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.goNativeStoryboard()
}
}
}
}
Connect.m
#import "React/RCTViewManager.h"
@interface RCT_EXTERN_MODULE(Connect, RCTViewManager)
RCT_EXTERN_METHOD(goToNative)
@end
ReactNativeFile.js
import React, { Component } from 'react';
import { StyleSheet, View, NativeModules, Text, TouchableOpacity } from 'react-native';
const { Connect } = NativeModules;
export default class Feed extends Component {
constructor(props) {
super(props)
this.done = false;
}
_changeView() {
this.done = true;
Connect.goToNative()
}
render() {
return (
this._changeView()}>
Press to Change to Native View
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'pink',
alignItems: 'center',
justifyContent: 'center',
}
});
That was it, it worked for me, hope it works for you as well. Thanks again to all the sources of references.