Inject React-Native component into any iOS app in 5 minutes with 5 easy steps

React-Native is the go to solution these days for most of the mobile apps. React-Native is pure Javascript, so if you already have the command over JS, native mobile apps are a piece of cake. What’s even more lucrative is, you can integrate any component made in react native in any of your iOS/Android native apps. With this possibility you can easily make reusable components to be bundled with your native apps.

Imagine a social networking app which requires a photo filter component. Why waste time on two separate code sets for iOS and Android when you can write a React-Native component and reuse it everywhere.

Write once, use everywhere“, is exactly what React-Native is all about. Let’s dive into the steps for how to integrate a React-Native component into an iOS app.

Full code set for this example can be picked from GITHUB. I’ll be using a simple example of, how to navigate to a react native component from a native iOS app and fall back.

9

 

STEP 1 (FOLDER STRUCTURE)

  1. Create a new folder named “iOS+React“. I’ll be referring it to as the “root-directory“. The name can be anything, no restrictions here. Inside this folder, create a new folder named “ios” and drag the files of your iOS project into this folder.  Now go into the “root-directory” and drag drop your React-Native project’s folder. The directory structure will look something like this:Screen Shot 2018-12-07 at 7.36.53 PM
  2. MySectionList is the folder containing my React Component and ReactNativeTest is the name of my iOS project.


STEP 2 (INSTALLING DEPENDENCIES)

  1. Create a new file named “package.json” in the “root-directory” folder, with the following contents:
    { “name”: “MyReactNativeApp”,
    “version”: “0.0.1”,
    “private”: true,
    “scripts”: { “start”: “node node_modules/react-native/local-cli/cli.js start” }
    }
  2. Open the terminal, and execute “yarn add react-native“. This will install the react native packages required by your iOS app. Now you should see a “node_modules” folder in the “root-directory“.
    3
  3. Go into the “ios>ReactNativeTest” folder and execute “pod init” from the terminal. You should see a new file named “podfile“. Open it in any text editor and paste the below contents into it (Get the contents of podfile from the GITHUB repo.):2
  4. Too much information? No worries, let me explain it. A pod file acts as a dependency manager in your iOS project. Similarly with these commands, you are downloading the dependencies required to bridge between your iOS and React-Native app.
  5. Mind the “target ‘ReactNativeTest‘ do” line in the pod file, it should match with the target of your iOS project. It’s the name of your project, unless you have changed it manually.

Some of you might be stuck on this step, because I too was not able to find the best way possible to connect two code sets. Singleton bridging is the answer to that. Your point of contact code will be isolated and at the same time, will be reusable.

 

STEP 3 (CREATE SINGLETON BRIDGING)

  1. Its better to have one singleton class to keep track of a React bridge, which will be responsible for handling the transactions between iOS and React-Native code.REACT-Bridge
  2. Create a new class named ReactMasterBridgeManager. Here is how the .h file looks like:
    3

  3. The single instance “sharedInstance“, will be used across the app to perform any operations on the bridge.
  4. “fireUpReactBridge”, will be used to instantiate the bridge.
  5. viewForModuleName“, method will instantiate react native view components over the bridge.
  6. nativeModuleForString“, will give back the native modules currently exposed and present on the bridge w.r.t the specific names.
  7. RCTBridge *bridge;,  is the single instance for bridge, which will be allocated for the full lifecycle of the app.
  8. Moving on to the .m file:
    3 4
  9. “RCTBridgeDelegate”, the important thing to notice here is, this delegate is providing the location of your Javascript code while we instantiate the Bridge. This is the local address on which JVM is running on your machine to handle the JS stuff.
  10. RCTRootView“, will actually host your react native component w.r.t the module name you provide in the react code. In this example, my index.js file in the react’s project has registered a component like this:

    import App from ‘./App'; imports the App.js file which is the first page of my react-native app.

    import {name as appName} from ‘./app.json';fetches the name of my react-native app, from app.json file (MySectionList).

    AppRegistry.registerComponent(appName, () => App);”registers a component by the name of “MySectionList” as a”appName” and when it will be called with RCTRootView, it will open the contents of App.js.

     

STEP 4 (EXPOSE NATIVE-iOS CODE TO REACT-NATIVE)

  1. Create a new file named “ReactCallbackManager“. This file will handle the navigation callbacks from “React-Native” in our iOS code. We will expose this file to react-native with two simple lines of code in .m file, but first lets see the contents of .h file:5
  2. “ReactCallBackmanagerProtocol”, can be used by any iOS view controller (housing a react-component) to get callbacks from React-Native code.
  3. Let’s look at the contents of .m file now, where we will expose this manager class to React-Native:
    6
  4. You can expose your file and methods with these two lines:

    RCT_EXPORT_MODULE“, will expose this file.
    RCT_EXPORT_METHOD, will expose the method named “dismissModalView“.

     

STEP 5 (PLAY WITH iOS and REACT-NATIVE VIEWS)

  1. Now we have all the setup required for the integration. Lets say you have a view controller in your old app and from there you want to present the react-native component. Just make a UIViewController as you would normally do via File > New File >.. etc from XCode. Let’s name it as MyReactViewController. This view controller will house your React-Native Component. You can present it from anywhere in you iOS app. Leave the .h file as is and edit the .m file with the below code:
    5
  2. Lets go step by step:

    viewDidLoad“: here we initialize our RCTRootView with the help of ReactMasterBridgeManager. Notice what name we provided to the moduleName parameter? Yes, its the name of our ReactNative project. We registered this name in the very end of STEP 3. At this step you should be able to see the React-Native component. But how to get out of this component and go back to native iOS app?

    “[[ReactMasterBridgeManager sharedInstance] nativeModuleForString:@”ReactCallbackManager”];”: this is our ACE card for making a connection between iOS and React Native. We exposed ReactCallbackManager to ReactNative, in STEP 4, now we need to get the instance of that exposed class and set its actionsDelegate property to self. This will guarantee that any calls made on ReactCallbackManager’s actionsDelegate method from the React-Native code will make it to this file.

  3. Lets open App.js in your React-native project (I use Nuclide &Atom as my go to text editor for playing with React, CSS or HTML). You need to make sure that NativeModules is imported among the other imports.

    “import {NativeModules…} from ‘react-native';”

  4. We have already exposed ReactCallbackManager to react native, now its time to use it.
    7
  5. Let’s understand the usage of exposed functionality.

    NativeModules.ReactCallbackManager“: this is how you get the access of your exposed class and then you can call the dismissModalView() method on it. It will call the RCT_EXPORT_METHOD(dismissModalView) method in ReactCallbackManager, which will in turn call the “dismissModalView” function on its actionDelegate. With this you have the custom reusable call back manager class, which can be used for any iOS view, for any other events such as forwardTap to present one more iOS controller and so on.

Lastly you need to run one simple command in the directory of your react-native component folder. For this example, that directory is /MySectionList. Go to this directory in the terminal and execute “npm start”. Your React-Native modules will fire up and your terminal will look like this:

8

Just run your iOS project from XCode, as you would do for any other project and play with your iOS and React code.

Full code set for this example can be found at GITHUB.

 

Leave a Reply

Your email address will not be published. Required fields are marked *


nine − 3 =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>