This tutorial is a walkthrough of how to get a JUCE project up and running with React Native. I am going to base my example on the React Native Navigation project which I have been using as the basis for React Native apps.
There are two layers to how a C++ application can interact with React Native:
First we have to get to the “native” API for the platform: Objective-C on iOS, and Java on Android. Going from Objective-C to C++ is fairly trivial as we can use Objective-C++, going back is a little more complicated. Going from Java to C++ is a little convoluted, having to go via the cryptic puzzle that is JNI, and going from C++ to Java is a little more complicated still. But its all doable once you get the basics going!
iOS — Setting up
The following assumes you have a standard JUCE app with a default (or close to) Main.cpp file.
Inside your Main.cpp you will find a MainWindow class. We will be creating a new MainWindow class, calling it MainWindowIOS, which will define an Objective-C++ class that will start up our React Native app, and allow us to show a JUCE Component as a UIView.
Add the following two files, ideally from the Projucer so they are added to the XCode project as well as your
.jucer file. I keep all my iOS only source files in a separate subfolder, i.e.
Next we need to modify our Main.cpp to use our new class. Remove the
MainWindow class defined within Main.cpp and copy it into a seperate file (e.g. MainWindow.h) in case you need it for a desktop version of your app.
Main.cpp should now look something like this:
Thats our initial code modifications done. Next we need to set up our node packages, import React Native and (if you choose to use it) the React Native Navigation library. This is done via CocoaPods. For a detailed walk-through please refer to the React Native Getting Started Guide linked below.
Tip: you might want to install yarn first and use it in place of npm.
And then here. Make sure you create your
Builds/iOS. See ya in a bit.
Integration With Existing Apps
This section will be updated shortly showing an integration into a more real world application such as the 2048 app…
Ok, so now you should have a
node_modules folder within your project folder, a
package.json file, and a
Podfile is written in Ruby in case you were wondering). You need to make a small change to adapt to how JUCE now names the Xcode target:
target 'MyApp' do
target 'MyApp (App)' do
Also (for compatibility with RNN at the time of writing), make sure you have version 0.31 of React Native in your
package.json, which should look like this:
"start": "node node_modules/react-native/local-cli/cli.js start --root ./ReactNative"
Now open up the generated
Podfile and add the following, adapted to your project:
Add the React Native Navigation library
If you want to use the React Native Navigation library we need to install it via npm and then add it to our Podfile.
npm install react-native-navigation@next --save
Now open up
Builds/iOS/Podfile in your editor and add RNN to it. Within your
target block add:
pod 'ReactNativeNavigation', :path => '../../node_modules/react-native-navigation'
Now we need to generate a Podspec for RNN.
npm install -g podspec-generator
Now we need to open up Projucer and add the following line, to Preprocessor definitions, both for debug and release builds:
We also need to change the Binary Location setting for both iOS builds to:
While we are in Projucer, we also need to add a custom PList entry to allow React Native to communicate with the node server in debug mode. Add the following to the Custom PList field:
Now you can go ahead and open your workspace in Xcode. Make sure it builds (Cmd+B). We’re not ready to run it just yet.
Adding a Custom View
We need some boilerplate code in order to make React Native aware of our JUCE Component.