Integrating React Native into an Existing App (iOS)

Nahuel A. Verón
codeburst
Published in
6 min readMay 28, 2017

--

You’ve probably heard about React Native, but if you haven’t, it’s basically a framework that allows you to use React inside of it, as if it were the web (with some differences, obviously). The key here is that you write Javascript, using some modules that react native provide you, and you got an native app, with components from the OS (or created by yourself) and is really fast and it works with almost the same code for android too.

What i found, is that is difficult but not impossible to implement react native in an existing application, the fact is that you have to had at least a little bit of knowledge on iOS development, on this case, but don't worry, i'll follow a step by step guide about how to do it, for simplicity sake, i'll start two empty projects: One being an simple iOS empty app on xcode, and the other an hello world example on react native.

Know the project name

In the future steps we'll be refer to the "project name" on steps of the code, this is the name that the main component is registering, it could be found on the file index.ios.js find a line that is calling the method registerComponent of AppRegistry like this:

AppRegistry.registerComponent(‘myAwesomeProject’, 
() => myAwesomeProject);

On this case, the first string is what we care about, since it told us that our project is called myAwesomeProject

Install the required tooling and set up your project

I'll not go into details on this one, so you can use whatever stack you like, but remember to install node & react-native-cli, because we're going to create a new project with that.

A npm i -g react-native-cli will work.

After that, we're going to create a new React Native Project (if you already have one skip this step) with react-native init myAwesomeProject where myAwesomeProject put your project name

It will start downloading bunch of packages via npm, starting the android/ios projects and finally you'll got this output:

Self Explanatory, right?

If like it says, we move into the directory project and ran react-native run-ios we'll got an emulator with our own example:

Heading back to your existing application, the first step is convert the project into the format that react native has, that means, if your project is under myAwesomeNativeApp should be now myAwesomeNativeApp/ios

Later on, move all the react-native folders and file into your project, except for the ios folder (and android, if you had a native android app), be careful of moving the hidden files too, those ones that starts with a dot.

Those are my files, but may vary between projects

After that, we had the environment ready, our app can receive the non-ios assets.

Setting up the required libraries

If we look both projects, we'll see this:

React Native on the left, my project on the right

We had a lot of libraries missing, if you don't use it, you can remove the tvOS targets and the tests, we'll not care about that one here.

On your new project, create a new group called Libraries , head to finder and inside your project, look for this path node_modules/react-native .

The react-native project will tell you what libraries you should include, if you select a project library, you'll see on the right their relative and absolute path

Those are the paths for React

We should replicate the same on our project, beware that should be relative to your project and inside node_modules , this will allow us later be able to update react native.

When we found the .xcodeproj that we want to include, simply drag it into the Libraries group, that for everyone.

After that, on both project go to the project description and build phases.

You'll need to move those who are under Link Binary With Libraries, simply press the "+" and look for the same filename.

Here is an example of what i have, those should be replicated on your destination project

After that, add a new script phase, using the plus sign on the top.

Call it "Bundle React Native code and images", open it and below the "Shell" input put this:

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

Now, head to "Build Settings", look for "Other Linker Flags" and add those:

Basically $(inherited) , -ObjC and -lc++

Setting up the Scheme

On your native project, look for the schema configuration, press "Edit Scheme" and go into the "Build" tab, first, turn off the Parallelize Build checkbox, press the plus sign and look for the "React" Project, add it. And make sure that is the first on the list.

You should finish having something like this

Integrate Your Code into a new View Controller (Swift)

First, because of the libraries are made with Objective-C but we're using swift, we'll need to create a Bridging Header, its easy, create a fake Objective-C file (those who end on .m) and Xcode will ask you to create a bridging header, simply put yes.

Im creating an useless .m file so Xcode generate my bridging header

After that, we can delete our .m file, and inside our bridging header, we should put:

#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>

Now, head back to Info.plist file, and add those properties:

Since we're going to work with the local packager, we should disable the App Transport policy, at least for now.

On the top of our AppDelegate.swift we'll add a new property that will have the view, it will be like this:

var rootView : RCTRootView?

And, to load it, inside our didFinishLaunchingWithOptions we'll put this statements:

Replace "myAwesomeProject" with your project name

Now, on the point where we want to start our application (could be a touch press on a button, for example), put this:

Integrate Your Code into a new View Controller (Objective-C)

In this case is more straightforward because is the same language that react-native is made, on this case, under AppDelegate.h add:

#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>

Inside the same, we're going to define a property that will hold the RootView, so, between the @interface and the @end tags put this line:

@property RCTRootView * rootView;

Head back into AppDelegate.m and add those lines inside the didFinishLaunchingWithOptions method:

Replace “myAwesomeProject” with your project name

Now, on the point where we want to start our application (could be a touch press on a button, for example), put this:

On the top of the file, add:

#import “AppDelegate.h”

Finally, run your application and you should see:

All done, we started react-native from our ViewController

--

--