Easy Tutorial:

CodePush-ify your React Native App

Ignacio Silveira avatarIgnacio Silveira
|
7 minutes read|may 14, 2021
Easy Tutorial: CodePush-ify your React Native App

CodePush is a cloud service that enables Cordova and React Native developers to deploy mobile app updates directly to their users’ devices.

A React Native app consists of JavaScript files and any accompanying images, which the packager bundles and distributes as part of a platform-specific binary (i.e., an .ipa or .apk file).

Once the app is released, updating the JavaScript code (e.g., fixing bugs or adding new features) or image assets requires recompiling and redistributing the entire binary, including the review time associated with app stores. This is one of the key challenges teams aim to overcome when working on scalable mobile products, especially within modern Cross-Platform App Development Services strategies.

The CodePush plugin helps get product enhancements to end users instantly, by keeping your JavaScript and images in sync with updates you release to the CodePush server. This way, your app gets the benefits of an offline mobile experience, as well as the “web-like” agility of side-loading updates as soon as they become available. It’s a win-win!

Note: Any changes to the product that affect native code (e.g., modifying your AppDelegate.m/MainActivity.java file, adding a new plugin) cannot be distributed via CodePush and must be updated via the appropriate store(s).

The operation is based on wrapping our app in a CodePush HOC (higher-order component) that checks for new updates in CodePush and reloads the app with the new changes.

React Native CodePush uses its own server to store a copy of each CodePush deployment and a control version in case a rollback is needed; this can be done almost instantly. All of this is managed through a user-friendly control panel provided by Microsoft, which not only allows you to control CodePush deployments but also conventional ones.

It also allows simultaneous testing of versions on a wide variety of devices and platforms.

The library has a wide variety of configuration parameters that, among other things, allow you to choose when to check for and download new versions of React Native CodePush for the app, and to use events to determine when each of these processes has completed. For example, you can notify the end-user that a new version will be installed the next time the app is restarted.

Since CodePush is a cloud service from AppCenter, the first thing you need to do is to create an account in the App Center dashboard.

Next, create two apps, one per OS (iOS and Android).

CodePush React Native

Make sure to select the release type production and the platform React Native.

CodePush React Native

Once the app is created, you’ll see instructions for integrating App Center analytics and crash reporting tools, which are NOT required to make CodePush work. But of course, you could install them if you want.

Next, continue with the CodePush setup. Go to Distribute => CodePush, then click the Create standard deployments button. App Center will create two environments, Staging and Production. We will only use Production in this guide.

CodePush

As you can see in the image above, you must install appcenter-cli and log in to AppCenter.

Once you have run the install command npm install -g appcenter-cli you will need to log in to AppCenter as follows:

  • Run appcenter login. This will open a browser and generate a new API token.
  • Copy the API token from the browser, and paste it into the command window.
  • The command window will display Logged in as {user-name}.
    Congratulations! You’ve successfully logged in and can run CLI commands.

Install the library in the React Native project

Once you’ve followed the general-purpose “getting started” instructions to set up your CodePush account, you can start CodePush-ifying your React Native app by running the following command from within your app’s root directory:

npm install --save react-native-code-push
or
yarn add react-native-code-push

iOS Setup

Plugin Installation and Configuration for React Native 0.60 version and above.

Run cd ios && pod install && cd ..  to install all the necessary CocoaPods dependencies.​

Open up the AppDelegate.m file, and add an import statement for the CodePush headers:

#import <CodePush/CodePush.h>

Find the following line of code, which sets the source URL for bridge for production releases:

return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];

Replace it with this line:

return [CodePush bundleURL];

This change configures your app to always load the latest version of its JS bundle.

 NOTE: The bundleURL method assumes your app’s JS bundle is named main.jsbundle. If you have configured your app to use a different file name, simply call the bundleURLForResource: method (which assumes you’re using the .jsbundle extension) or bundleURLForResource:withExtension: method instead, in order to overwrite that default behavior.

Typically, you’ll only want to use CodePush to resolve the location of your JS bundle within release builds, and therefore, we recommend using the DEBUG pre-processor macro to dynamically switch between using the packager server and CodePush, depending on whether you are debugging or not.

This will make it much simpler to ensure you get the right behavior you want in production, while still being able to use the Chrome Dev Tools, live reload, etc. at debug-time.

Your  sourceURLForBridge  method should look like this:

– (NSURL*)sourceURLForBridge:(RCTBridge *)bridge
{
#if
DEBUG
 return[[RCTBundleURLProvider sharedSettings]
jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
 #else
  return [CodePush bundleURL];
#endif

}

Add the Deployment key to  Info.plist :

To let the CodePush runtime know which deployment it should query for updates against, open your app’s Info.plist file and add a new entry named CodePushDeploymentKey , whose value is the key of the deployment you want to configure this app against.

You can retrieve this value by running appcenter codepush deployment list -a <ownerName>/<appName> -k  and copying the value of the  Key  column which corresponds to the deployment you want to use.

In order to effectively make use of the  Staging and  Production deployments that were created along with your CodePush app, refer to the multi-deployment testing docs below before actually moving your app’s usage of CodePush into production.

Android Setup

Plugin Installation and Configuration for React Native 0.60 version and above.

In the android/settings.gradle file, make the following additions at the end of the file:


include ':app', ':react-native-code-push'
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, ‘../node_modules/react-native-code-push/android/app’)


In the android/app/build.gradle file, add the codepush.gradle file as an additional build task definition underneath react.gradle:


apply from: "../../node_modules/react-native/react.gradle"
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"


Update the MainApplication.java file to use CodePush via the following changes:


// 1. Import the plugin class.
import com.microsoft.codepush.react.CodePush;

public class MainApplication extends Application implements
ReactApplication
{

    private final ReactNativeHost mReactNativeHost = new
ReactNativeHost(this) {

        …
        // 2. Override the getJSBundleFile method in order to let
        // the CodePush runtime determine where to get the JS
       // bundle location from on each app start

        @Override
        protected String getJSBundleFile() {
            return CodePush.getJSBundleFile();

        }
    };
}


Add the Deployment key to strings.xml:

To let the CodePush runtime know which deployment to query for updates, open your app’s strings.xml file and add a new string called CodePushDeploymentKey, whose value is the key of the deployment you want to configure this app against.

You can retrieve this value by running appcenter codepush deployment lista <ownerName>/<appName>k and copying the value of the Key column which corresponds to the deployment you want to use.

In order to effective use of the Staging and Production deployments that were created along with your CodePush app, refer to the multi-deployment testing docs below before actually moving your app’s usage of CodePush into production.

The strings.xml should look like this:

<resources>
    <string name="app_name">AppName</string>
    <string moduleConfig="true"
 
name="CodePushDeploymentKey">DeploymentKey</string>
</resources>

Modify JS Code

Wrap your root component with the codePush higher-order component (HOC):

For class component:

import codePush from "react-native-code-push";

class MyApp extends Component {
}

MyApp = codePush(MyApp);


For functional component:

import codePush from "react-native-code-push";

let MyApp: () => React$Node = () => {
}

MyApp = codePush(MyApp);


Run the app to make sure it’s working properly and pay attention to the metro server logs. You should be able to see that you are asking CodePush if there is any version to download.

Release a version to CodePush

Go to AppCenter -> Distribute -> CodePush

Find the release command and make sure you are using the right params.

The release command is:

appcenter codepush release-react -a <owner_name>/<app_name> -d Production


When the upload is complete, reload the AppCenter dashboard and make sure your release appears.


Now run the app again and check the Metro server logs—you should be able to download the version from CodePush. On the second session (after closing and reopening the app), this new version will be installed on the device, and you will see your changes reflected. To ensure everything works as expected, it’s also important to follow best practices when debugging updates delivered through CodePush.NOTE:
If you want to force the app to install the latest code push version in the same session in which the app downloads the bundle, you must mark the code push version as a required update in the App Center dashboard.

CodePush React Native

Read more articles

Next.js 13: Powerful Framework for Server-rendered Apps

may 23, 2023 | 5 min read

Next.js 13: Powerful Framework for Server-rendered Apps

JavaScriptNext JS
React Native Input: How to Enter Text and Delete It Easily

jul 23, 2021 | 5 min read

React Native Input: How to Enter Text and Delete It Easily

JavaScriptReact Native
React Native Vector Icons: Set the Tone for your App

jun 7, 2021 | 5 min read

React Native Vector Icons: Set the Tone for your App

AndroidiOS

Hit subscribe
to
stay in the loop!

Your monthly dose of tech insights,
industry trends, and
effectus updates.