React Native Tutorial: Integrating in an Existing App

In this React Native tutorial, you’ll learn how to integrate React Native into an existing app, demonstrating one approach to adoption of the framework. By Christine Abernathy.

Leave a rating/review
Save for later
Share

The React Native framework lets you build native apps using React concepts. With React Native, you can build responsive native apps while enjoying the benefits of various web development paradigms, such as viewing your changes without recompiling the code.

Have you wanted to see how React Native fits into your app and development workflow, but without completely converting your existing app? Good news – you can incrementally add React Native to your app by inserting one or more React Native views into your app and letting React Native drive that experience.

This React Native tutorial will guide you through integrating React Native into an existing Swift application. You’ll build upon an existing application called Mixer that displays mixer events and gives you an opportunity to rate them.

Before you get started, be sure to check out the React Native Tutorial: Building Apps with JavaScript that walks you through the basics. You’ll also need some familiarity with CocoaPods to work through this tutorial.

Getting Started

Download the starter project for this tutorial and unzip it. Run the project found in the Mixer-Starter/ios folder to see what you have to work with.

The home screen displays a list of mixers. Tap the first one to see the mixer details, then tap Add Rating to see the view where you can add your own rating. It’s presently empty – and waiting for your upcoming implemention using React Native! :]

Starter app overview

Add a React Native View

Close the Mixer project in Xcode. Before you start coding, you’ll have to install the prerequisites for React Native.

If you don’t have CocoaPods installed, execute the following command in Terminal:

gem install cocoapods

Next, install Homebrew using the instructions on the Homebrew website.

Then, execute the following command in Terminal to install Node.js through Homebrew:

brew install node

Finally, use the following command to instruct Homebrew to install watchman, which is used by React Native to detect file changes:

brew install watchman

You now have the basic React Native scaffolding in place. Now you can install the modules your project will use.

In Terminal, navigate to the starter project’s js subdirectory and create a file named package.json. Add the following to the file:

{
  "name": "mixer",
  "version": "1.0.0",
  "private": true,
  "description": "Mixer",
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "dependencies": {
    "react": "~15.3.1",
    "react-native": "~0.34.0"
  }
}

This lists the dependencies for your app and sets up the start script. Run the following command to install the required Node.js modules:

npm install

You should see a new node_modules subdirectory that contains the React and React Native modules. The React Native module includes code needed to integrate with a native app. You’ll use CocoaPods to make Xcode aware of these libraries.

In Terminal, navigate to the starter project’s ios subdirectory and create a file named Podfile with the following content:

use_frameworks!
target 'Mixer'
pod 'React', :path => '../js/node_modules/react-native', :subspecs => [
  'Core',
  'RCTImage',
  'RCTNetwork',
  'RCTText',
  'RCTWebSocket',
]

The above configuration specifies a subset of libraries to load from the React Podspec. The specs listed here allow you to work with features such as views, text, and images.

Run the following command to install the dependencies:

pod install

Your output should look like this:

Analyzing dependencies
Fetching podspec for `React` from `../js/node_modules/react-native`
Downloading dependencies
Installing React (0.34.0)
Generating Pods project
Integrating client project

[!] Please close any current Xcode sessions and use `Mixer.xcworkspace` for this project from now on.
Pod installation complete! There are 5 dependencies from the Podfile and 1 total pod installed.

Open Mixer.xcworkspace, and run your app to verify you don’t have any build errors. The app should look exactly the same as it did before:

Mixer Home

Creating a Simple View

Using your favorite text editor, create a new file named index.ios.js and save it in the js directory. Add the following content to that file:

'use strict';
// 1
import React from 'react';
import ReactNative, {
  AppRegistry,
  StyleSheet,
  Text,
  View,
} from 'react-native';

// 2
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'green',
  },
  welcome: {
    fontSize: 20,
    color: 'white',
  },
});

// 3
class AddRatingApp extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>We're live from React Native!!!</Text>
      </View>
    )
  }
}

// 4
AppRegistry.registerComponent('AddRatingApp', () => AddRatingApp);

Here’s a step-by-step of what’s going on above:

  1. This loads the react and react-native modules, and the destructuring assignments let you drop the React/ReactNative prefixes when calling methods in those modules.
  2. Next, you define the stylesheets used in the UI.
  3. The next bit defines AddRatingApp with render() to display some welcome text.
  4. AddRatingApp serves as the application entry point’s root component.

In Xcode, open AddRatingViewController.swift and add the following import directive:

import React

Next, add the following instance variable that represents the React Native root view:

var addRatingView: RCTRootView!

Then, add the following code to the end of viewDidLoad():

addRatingView = RCTRootView(
    bundleURL: URL(string: "http://localhost:8081/index.ios.bundle?platform=ios"),
    moduleName: "AddRatingApp",
    initialProperties: nil,
    launchOptions: nil)
self.view.addSubview(addRatingView)    

This initializes an instance of RCTRootView with the app bundle served up from index.ios.js. It configures AddRatingApp as module name to run initially.

Finally, set the root view’s frame in viewDidLayoutSubviews by adding the following code to the end:

addRatingView.frame = self.view.bounds

For security reasons, Apple by default blocks HTTP access to URLs. You’ll have to make an exception so you can load your bundle from the development server running on http://localhost.

In Xcode, open Info.plist and perform the following:

  1. Add the NSAppTransportSecurity key as a Dictionary type.
  2. Add the NSExceptionDomains key with Dictionary type under NSAppTransportSecurity.
  3. Add a key named localhost of type Dictionary under NSExceptionDomains.
  4. Add the NSTemporaryExceptionAllowsInsecureHTTPLoads key with the value YES under localhost.

When done, your Info.plist should look like the following:

Mixer Info.plist

In Terminal, go to your js directory and execute the following command to start the React Native development server:

npm start

After a few seconds, you should see something like the following:

Development server running

Note: If you receive an error stating that none of the files are listed in global config root_files then run the following command to initialize Git: git init.

If you still see the same error, run the following command to initialize a watchman configuration file in the js directory: echo "{}" > .watchmanconfig

Run the project in Xcode. Tap any mixer, tap Add Rating, and you should see the welcome text view:

Mixer first React Native app

The first time you run your app, it may take a little time for the packager to load the bundle.

Christine Abernathy

Contributors

Christine Abernathy

Author

Over 300 content creators. Join our team.