2. Talking like a React Native
In this instalment of our React Native with C++ series, we first learn how to setup React Native to communicate with Objective-C and Java.
Mobile development is inherently a multi-lingual enterprise. Usually this means writing the same functionality in multiple languages which is a bad practice. In this series I want to explore an interesting technique for simplifying our codebase by utilising the power of C++ to achieve more maintainable cross platform development.
Other articles in this series:
- Why React Native needs C++
- Talking like a React Native
- Mobile to C++ with Djinni
- Connect React Native to C++
On the road from React Native to C++
In our last instalment, I cover why we would want to use C++ alongside React Native to create DRY cross platform code. Over the next few articles I want to cover how exactly to do that step by step.
So let’s get started getting React Native talk to C++. The broad process goes as follows:
- Get React Native talking to Objective-C and Java
- Generate our C++ bridge with Djinni
- Connect Objective-C and Java to our C++ Djinni bridge
This particular article covers the first point on the list and can be used as a guide to getting React Native talking to iOS and Android. If you already have this set up you may want to skip ahead to the next instalment where I cover more on how the C++ bridge works.
React Native Bridge — Talking like a Native
For folks coming to this article not from a JavaScript background, before we begin we should ensure we have yarn installed. Yarn is an alternative package manager that serves a similar function to npm.
On macOs you might use homebrew:
brew install yarn
You need to check the correct installation method for your system.
Now we have Yarn installed we can proceed with creating a blank React Native project. To do that I like using npx as it ensures our dependencies are up to date.
Now, let’s alter our React file to accept a message from NativeModules:
It’s time now to get some information to the NativeModules object by writing some native code. First let’s start with iOS.
React Native Bridge — iOS
This section focussed on how to get React Native talking to iOS specifically.
Let’s first create a folder to hold our bridge code.
Now create a header file for our bridging code
And some simple implementation to get a message to JavaScript. To learn more about React Native Bridge you can have a look at the documentation.
This is basically all the code we have to write to get JavaScript to call Objective-C functions. It is worth noting that by default ReactNative will call the NativeModule export the class name you define. If it encounters a name that starts with RCT
such as RCTHelloWorld
it will remove the prefix and call the module HelloWorld
as is happening here. So some sprinkles of magic fairy dust… normally this sort of thing annoys me but that’s what happens as you leave the familiar explicit culture of JavaScript.
Add the bridging files to Xcode
Open up ios/CppReactNative.xcodeproj
in Xcode.
Next add the contents of ios/ReactBridge
folder as a group to your CppReactNative
group by right clicking the CppReactNative
group. Groups are virtual folders within xcode. Ensure the “copy files” checkbox is not checked as this may mean you might be building from a cached copy and not your actual code which might cause problems. Also ensure your target is selected so Xcode knows to include those files when compiling your target.
By adding the folder, the classes you just created will be picked up automatically and be made available to React Native once you build your project.
Your Xcode file tree should look something like this:
Build your project using the `⌘+R` keyboard shortcut and you should see your app display a message from Objective-C.
React Native Bridge — Android
Before pushing ahead let’s keep this setup cross platform and setup NativeModules for Android. This section focussed on how to get React Native talking to Android specifically.
First create a package folder:
mkdir -p ./android/app/src/main/java/com/cppreactnative/helloworld
Now the module class:
We then need to create a package that uses the module. This is how we package up bridging code for React Native Android. If this seems like extra steps in Objective-C dependencies are slurped up automatically but they are not for Java and we need to be explicit.
Finally we add our package to our application’s `MainApplication.java` by adding the following line to the getPackages() method:
Ensure you have Android studio setup according to Facebook’s instructions and build and run your project.
If you don’t still have the terminal session running from your Xcode build, you might want to run yarn start
from your project root in a terminal. Once that is done your JS code should load up just fine and you should see your message from Android appear in the emulator:
Our app is now speaking like a native!
So far in this instalment we have covered connecting React Native with Objective-C and Java. In the next instalment in this series we will cover setting up our C++ bridge with Djinni.
You can find the code associated with this article on my github.
Other articles in this series:
- Why React Native needs C++
- Talking like a React Native
- Mobile to C++ with Djinni
- Connect React Native to C++
This article is a living document and I am constantly learning please reach out to me if you want to contribute or see anything inaccurate here.
You can follow Rudi Yardley on Twitter as @rudiyardley or on Github as @ryardley