In the beginning, we have to answer the question: What is a brownfield app? 

The term brownfield was originally used in construction and development to reference land that at some point was occupied by a permanent structure. In a brownfield project, the structure would need to be demolished or renovated. Today, the term brownfield project is used in many industries, including software development, to mean to start a project based on prior work or to rebuild (engineer) a product from an existing one.

~Vangie Beal

So in our case, it means that we want to run a react-native application as a part of a native one that is already developed with technologies like Java, Kotlin, Objective-C or Swift.

How does it work?

Let’s assume that we have a native iOS application where we want to create a new screen using react-native app that is already implemented. That screen will navigate to another screen inside the react-native application.

In order to make it works, we need to do a few things.

Add react-native to project:

  • First of all, we need to add our react-native app to existing native project. We will want to decide what parts of the React Native framework you would like to integrate. We will use CocoaPods for it. Let’s edit or create Podfile in the native project and add React and all needed subspecs with path pointed to node_modules and run pod install command

Run react-native app:

  • When the react-native app is properly linked to the native one, we need to create a class that implements RCTBridgeDelegate – at least thesourceURLForBridge method that is needed to specify which JS bundle will be used.
  • Then create a react-native bridge instance ( RCTBridge ) with the previously implemented class as the delegate and launchingOptions dictionary if needed.
  • Create ViewController where we will set therootView of the react-native app as a view property.
  • Finally, we can push our react-native view controller to the stack

Additional steps:

Note: In debug mode, we need packager to serve JS bundle. However, Apple has blocked implicit cleartext HTTP resource loading. So we need to add the following our project’s Info.plist (or equivalent) file.

In addition, we can add scripts to Build Phases which will build react-native bundle and images for us





export NODE_BINARY=node ../node_modules/react-native/scripts/react-native-xcode.sh

And the script that will run the packager

Navigation issues:

We have all set, however, there is an issue with swipe to back functionality. We are not able to back to our native screen via a swipe gesture nor by Go Back button. We need some mechanism that would make possible to say from react-native to the native part that we want back to our native screen or that we want to enable/disable native PopGestureRecognizer . It could be solved by a react-native native module which will send notification by NSNotificationCenter .

BUT wait… Can’t it be done in simpler way? Do we really need to take care of RCTBridgeDelegate, RCTBridge, RCTRootView?

Of course, it might be easier 🙂 We can use react-native-brownfield package which will help us with navigation’s issues and provide a nice API to run a react-native application.

How does it work with react-native-brownfield?

We want to achieve exactly the same effect as before but we will use react-native-brownfield library

Add react-native to project:

The theory is the same as I described in the previous part of this article but with some facilities. In order to run our react-native app in native one using react-native-brownfield we need to add that package as a dependency to package.json using:

or

Next, we need to add react-native app as we did in Add react-native to project point using CocoaPods.

Run react-native app:

And now the fun begins 🙂 Instead of creating a bridge by ourselves we can simply use ReactNativeBrownfield package.

Import ReactNativeBrownfield package and create the instance of it with the entry file name.

We are ready to run react-native app using startReactNative method of our reactNativeBrownfieldManager

And that’s it. We can push react-native app view controller to the navigation stack with user-friendly API.

Additional steps:

All additional steps are needed to be added here as well

  • Edit Info.plist file to allow connection to the packager
  • Add script to Build Phases to run packager
  • Add script to BuildPhases to bundle JS code and assets

Navigation issues:

react-native-brownfield comes with a solution for issues mentioned above. It exposes two methods that can be used in JS code to toggle back gesture and pop to a native screen.

  • ReactNativeBrownfield.setNativeBackGestureAndButtonEnabled – to toggle iOS native back gesture
  • ReactNativeBrownfield.popToNative – to pop to the native screen

And voilà! We are ready to go 🙂

Conclusion:

Lastly, it is a popular thing to use react-native within existing native apps especially by larger organizations that have multiple teams working on the same app for multiple platforms. Thanks to react-native-brownfield the integration is easier, enjoyable and some issues that exist in every react-native brownfield app are solved 🙂

Working examples of using react-native-brownfield are inside example directory

No Comments