@@ -32,6 +32,13 @@ class ReactNativeBrownfieldDelegate: RCTDefaultReactNativeFactoryDelegate {
3232 private var onBundleLoaded : ( ( ) -> Void ) ?
3333 private var delegate = ReactNativeBrownfieldDelegate ( )
3434
35+ private func checkFactoryInitialized( launchOptions: [ AnyHashable : Any ] ? = nil ) {
36+ if reactNativeFactory == nil {
37+ delegate. dependencyProvider = RCTAppDependencyProvider ( )
38+ self . reactNativeFactory = RCTReactNativeFactory ( delegate: delegate)
39+ }
40+ }
41+
3542 /**
3643 * Path to JavaScript root.
3744 * Default value: "index"
@@ -71,10 +78,12 @@ class ReactNativeBrownfieldDelegate: RCTDefaultReactNativeFactoryDelegate {
7178 private var reactNativeFactory : RCTReactNativeFactory ? = nil
7279 /**
7380 * Root view factory used to create React Native views.
81+ * Always proxies the currently active React Native factory so restarting
82+ * React Native yields a fresh root view factory instance.
7483 */
75- lazy private var rootViewFactory : RCTRootViewFactory ? = {
76- return reactNativeFactory? . rootViewFactory
77- } ( )
84+ private var rootViewFactory : RCTRootViewFactory ? {
85+ reactNativeFactory? . rootViewFactory
86+ }
7887
7988 /**
8089 * Starts React Native with default parameters.
@@ -88,7 +97,9 @@ class ReactNativeBrownfieldDelegate: RCTDefaultReactNativeFactoryDelegate {
8897 initialProps: [ AnyHashable : Any ] ? ,
8998 launchOptions: [ AnyHashable : Any ] ? = nil
9099 ) -> UIView ? {
91- rootViewFactory? . view (
100+ checkFactoryInitialized ( launchOptions: launchOptions)
101+
102+ return rootViewFactory? . view (
92103 withModuleName: moduleName,
93104 initialProperties: initialProps,
94105 launchOptions: launchOptions
@@ -112,9 +123,7 @@ class ReactNativeBrownfieldDelegate: RCTDefaultReactNativeFactoryDelegate {
112123 */
113124 @objc public func startReactNative( onBundleLoaded: ( ( ) -> Void ) ? , launchOptions: [ AnyHashable : Any ] ? ) {
114125 guard reactNativeFactory == nil else { return }
115-
116- delegate. dependencyProvider = RCTAppDependencyProvider ( )
117- self . reactNativeFactory = RCTReactNativeFactory ( delegate: delegate)
126+ checkFactoryInitialized ( launchOptions: launchOptions)
118127
119128 if let onBundleLoaded {
120129 self . onBundleLoaded = onBundleLoaded
@@ -136,6 +145,25 @@ class ReactNativeBrownfieldDelegate: RCTDefaultReactNativeFactoryDelegate {
136145 }
137146 }
138147
148+ /**
149+ * Stops React Native and releases the underlying factory instance.
150+ */
151+ @objc public func stopReactNative( ) {
152+ if !Thread. isMainThread {
153+ DispatchQueue . main. async { [ weak self] in self ? . stopReactNative ( ) }
154+ return
155+ }
156+
157+ guard let factory = reactNativeFactory else { return }
158+
159+ factory. bridge? . invalidate ( )
160+
161+ NotificationCenter . default. removeObserver ( self )
162+ onBundleLoaded = nil
163+
164+ reactNativeFactory = nil
165+ }
166+
139167 @objc private func jsLoaded( _ notification: Notification ) {
140168 onBundleLoaded ? ( )
141169 onBundleLoaded = nil
0 commit comments