Skip to content

Conversation

californiandreamer
Copy link

Summary

  • Adds public iOS API stopReactNative() to deallocate the React Native runtime created by RCTReactNativeFactory and allow clean re‑initialization later. Fixes #134.
  • Old Architecture: calls bridge.invalidate() to tear down JS and native modules.
  • New Architecture: releases the runtime by dropping strong references (no public stop API on RCTHost).
  • Prevents crashes when pushing a React Native screen after stopping:
    • Adds checkFactoryInitialized() and uses it in view() to re-create the factory on demand if it was stopped.
    • ReactNativeViewController now guards against a nil view with a safe placeholder, avoiding SwiftUI bridging crashes.
  • Removes stale lazy caching of rootViewFactory to avoid retaining the old runtime.
  • Documentation updates for the new API and usage:
    • docs/SWIFT.md
    • docs/OBJECTIVE_C.md
  • Backwards compatible: existing startReactNative() API remains; view() now self‑heals if RN was previously stopped.

Test plan

  • Press the “Stop React Native” (to check app won't crash if stopReactNative called before RN was initialize)
  • Push RN screen → pop → tap the “Stop React Native” button → push again (no crash).
  • Repeat with both architectures toggled.
  • Watch the Xcode Instruments graph to confirm RN objects are released after stop (RSS may not drop immediately).

Copy link
Member

@okwasniewski okwasniewski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this! 🚀

Overall looks good, left couple of questions.

return
}

guard let factory = reactNativeFactory else { return }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
guard let factory = reactNativeFactory else { return }
guard let reactNativeFactory else { return }

Comment on lines +35 to +40
private func checkFactoryInitialized(launchOptions: [AnyHashable: Any]? = nil) {
if reactNativeFactory == nil {
delegate.dependencyProvider = RCTAppDependencyProvider()
self.reactNativeFactory = RCTReactNativeFactory(delegate: delegate)
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we create w getter on the factory that initizalizes it if it's nil? It should remove the need to call this function

Comment on lines +157 to +162
factory.bridge?.invalidate()

NotificationCenter.default.removeObserver(self)
onBundleLoaded = nil

reactNativeFactory = nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you test the scenario of what happens when react native view is still shown while calling this? Let's make sure it doesn't crash the app.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe there is a way to detect current react native surfaces in the app and show a warning if the user tries to do this with views still on screen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add method to deallocate reactNativeFactory instance
2 participants