Follow this instruction integration-with-existing-apps
You may need to install “react”: “x.x.x” by yourself. It is recommened to create an example React Native AwesomeProject for reference.
Android
Add code to start the React Native runtime and tell it to render JS component
To do this, we’re going to create an Activity
that creates a ReactRootView
, starts a React application inside it and sets it as the main content view.
class MyReactActivity : Activity(), DefaultHardwareBackBtnHandler { private lateinit var reactRootView: ReactRootView private lateinit var reactInstanceManager: ReactInstanceManager override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) SoLoader.init(this, false) reactRootView = ReactRootView(this) val packages: List<ReactPackage> = PackageList(application).packages // Packages that cannot be autolinked yet can be added manually here, for example: // packages.add(MyReactNativePackage()) // Remember to include them in `settings.gradle` and `app/build.gradle` too. reactInstanceManager = ReactInstanceManager.builder() .setApplication(application) .setCurrentActivity(this) .setBundleAssetName("index.android.bundle") .setJSMainModulePath("index") .addPackages(packages) .setUseDeveloperSupport(BuildConfig.DEBUG) .setInitialLifecycleState(LifecycleState.RESUMED) .build() // The string here (e.g. "MyReactNativeApp") has to match // the string in AppRegistry.registerComponent() in index.js reactRootView?.startReactApplication(reactInstanceManager, "MyReactNativeApp", null) setContentView(reactRootView) } //////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////// override fun invokeDefaultOnBackPressed() { super.onBackPressed() } override fun onBackPressed() { reactInstanceManager.onBackPressed() super.onBackPressed() } override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean { if (keyCode == KeyEvent.KEYCODE_MENU && reactInstanceManager != null) { reactInstanceManager.showDevOptionsDialog() return true } return super.onKeyUp(keyCode, event) } //////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////// override fun onPause() { super.onPause() reactInstanceManager.onHostPause(this) } override fun onResume() { super.onResume() reactInstanceManager.onHostResume(this, this) } override fun onDestroy() { super.onDestroy() reactInstanceManager.onHostDestroy(this) reactRootView.unmountReactApplication() } }
Fix error
If you find error with Gradle sync
- Rename your Android project folder to android
- Re-open it, it should be built well
Call ReactActivity in MainActivity
val intent = Intent(this, MyReactActivity::class.java) startActivity(intent)
iOS
Fix errors
- pod init fails
RuntimeError – [Xcodeproj] Unknown object version.
Fix it by running sudo gem update xcodeproj - Create Podfile by copying content of Podfile from AwesomeProject Podfile
require_relative '../node_modules/react-native/scripts/react_native_pods' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' platform :ios, '12.4' install! 'cocoapods', :deterministic_uuids => false target 'NativeIOS' do config = use_native_modules! # Flags change depending on the env values. flags = get_default_flags() use_react_native!( :path => config[:reactNativePath], # Hermes is now enabled by default. Disable by setting this flag to false. # Upcoming versions of React Native may rely on get_default_flags(), but # we make it explicit here to aid in the React Native upgrade process. :hermes_enabled => true, :fabric_enabled => flags[:fabric_enabled], # Enables Flipper. # # Note that if you have use_frameworks! enabled, Flipper will not work and # you should disable the next line. :flipper_configuration => FlipperConfiguration.enabled, # An absolute path to your application root. :app_path => "#{Pod::Config.instance.installation_root}/.." ) target 'NativeIOSTests' do inherit! :search_paths # Pods for testing end target 'NativeIOSUITests' do # Pods for testing end end
- Have to add this into info.plist to be able to load localhost metro bundle file
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>localhost</key> <dict> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> </dict> </dict>
- Build failed: Library not loaded: @rpath/hermes.framework/hermes
Create a new React Native view controller
// ViewController.swift import UIKit import React class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } override func loadView() { loadReactNativeView() } func loadReactNativeView() { let jsCodeLocation = URL(string: "http://localhost:8081/index.bundle?platform=ios")! let rootView = RCTRootView( bundleURL: jsCodeLocation, moduleName: "MyReactNativeApp", // This must be React Native registered component name initialProperties: nil, launchOptions: nil ) self.view = rootView } }
Delete Main.storyboard
- Delete file itself
- Delete its info.plist
- Delete its name in Main interface
Update SceneDelegate.swift for iOS >=13 targeted
import UIKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). guard let windowScene = (scene as? UIWindowScene) else { return } let window = UIWindow(windowScene: windowScene) window.rootViewController = ViewController() self.window = window window.makeKeyAndVisible() } }
Update AppDelegate.swift for iOS <= 12 targeted
import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { window = UIWindow() window?.rootViewController = ViewController() window?.makeKeyAndVisible() return true } }
Ref:
how-to-add-react-native-to-an-existing-ios-app-in-2022
remove-main-storyboard
Leave a Reply