Skip to content

Commit 04b875c

Browse files
author
Nazar Sydiaha
committed
feat: add stopReactNative method
1 parent e7d3530 commit 04b875c

File tree

3 files changed

+50
-4
lines changed

3 files changed

+50
-4
lines changed

docs/OBJECTIVE_C.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@ Examples:
7070
}, launchOptions];
7171
```
7272

73+
`stopReactNative`
74+
75+
Stops React Native and releases the underlying runtime. Safe to call multiple times. Call it after all React Native views are dismissed.
76+
77+
Examples:
78+
79+
```objc
80+
[[ReactNativeBrownfield shared] stopReactNative];
81+
```
82+
7383
`view`
7484

7585
Creates a React Native view for the specified module name.

docs/SWIFT.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@ ReactNativeBrownfield.shared.startReactNative(onBundleLoaded: {
7070
}, launchOptions: launchOptions)
7171
```
7272

73+
`stopReactNative`
74+
75+
Stops React Native and releases the underlying runtime. Safe to call multiple times. Call it after all React Native views are dismissed.
76+
77+
Examples:
78+
79+
```swift
80+
ReactNativeBrownfield.shared.stopReactNative()
81+
```
82+
7383
`view`
7484

7585
Creates a React Native view for the specified module name.

ios/ReactNativeBrownfield.swift

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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"
@@ -88,7 +95,9 @@ class ReactNativeBrownfieldDelegate: RCTDefaultReactNativeFactoryDelegate {
8895
initialProps: [AnyHashable: Any]?,
8996
launchOptions: [AnyHashable: Any]? = nil
9097
) -> UIView? {
91-
reactNativeFactory?.rootViewFactory.view(
98+
checkFactoryInitialized(launchOptions: launchOptions)
99+
100+
return reactNativeFactory?.rootViewFactory.view(
92101
withModuleName: moduleName,
93102
initialProperties: initialProps,
94103
launchOptions: launchOptions
@@ -112,9 +121,7 @@ class ReactNativeBrownfieldDelegate: RCTDefaultReactNativeFactoryDelegate {
112121
*/
113122
@objc public func startReactNative(onBundleLoaded: (() -> Void)?, launchOptions: [AnyHashable: Any]?) {
114123
guard reactNativeFactory == nil else { return }
115-
116-
delegate.dependencyProvider = RCTAppDependencyProvider()
117-
self.reactNativeFactory = RCTReactNativeFactory(delegate: delegate)
124+
checkFactoryInitialized(launchOptions: launchOptions)
118125

119126
if let onBundleLoaded {
120127
self.onBundleLoaded = onBundleLoaded
@@ -136,6 +143,25 @@ class ReactNativeBrownfieldDelegate: RCTDefaultReactNativeFactoryDelegate {
136143
}
137144
}
138145

146+
/**
147+
* Stops React Native and releases the underlying factory instance.
148+
*/
149+
@objc public func stopReactNative() {
150+
if !Thread.isMainThread {
151+
DispatchQueue.main.async { [weak self] in self?.stopReactNative() }
152+
return
153+
}
154+
155+
guard let factory = reactNativeFactory else { return }
156+
157+
factory.bridge?.invalidate()
158+
159+
NotificationCenter.default.removeObserver(self)
160+
onBundleLoaded = nil
161+
162+
reactNativeFactory = nil
163+
}
164+
139165
@objc private func jsLoaded(_ notification: Notification) {
140166
onBundleLoaded?()
141167
onBundleLoaded = nil

0 commit comments

Comments
 (0)