DEV Community

Cover image for Codepush-fy your react-native app in 5 minutes! πŸš€
Jacob Park
Jacob Park

Posted on

Codepush-fy your react-native app in 5 minutes! πŸš€

What is codepush?

Codepush is awesome tool that makes it possible to bypass store review when updating react-native(or cordova) apps.

It works like cloud storage of app bundle. After you set everything up and publish your app to the market, on every launch your app can check if there's a new version and updates itself.

It supports iOS, android and windows apps created with react-native or cordova.

They say it updates only javascript bundle(when it's RN app), so some updates including assets or native code might cause apps to crash and roll back to older version.

But while using this tool for about four months, no such accident has ever happened. So unless you add native modules or code some out-of-js stuff, you don't have to worry about it.

How can I use it?

1. Install Appcenter-cli

yarn global add appcenter-cli

or

npm i -g appcenter-cli

2. Add your app and deployment track to Appcenter.

First, you should login to appcenter using appcenter-cli.

appcenter login # browser will open up. after you login to appcenter, you'll get auth code to type in terminal

Now you need to create an app ( not real application, just think this as remote repository of app bundle ) to appcenter.

# change appname and os as you want
appcenter apps create -d {appname} -o {os}(Android/iOS) -p React-Native

In production, I create two apps named appname-ios, appname-android each. After this, you can add deployment track of your app. Consider it as a branch of your remote app bundle repository. You can create multiple tracks and control those different update streams seperately.

appcenter codepush deployment add -a {username/appname} {trackname}

When you do this, you'll get a deployment key on your terminal. You will need this, copy it. If you cleared your terminal by accident, you can re-gain it by this command.

appcenter codepush deployment list -a {username/appname} -k

3. Add codepush to your app.

Add codepush dependency on your react-native project.

yarn add react-native-code-push

Setting up iOS

  • Add native dependency for iOS

At your root directory of the react-native project.

cd ios && pod install && cd ..
  • Edit AppDelegate.m.

Import header for codepush.

#import "AppDelegate.h"

#import <CodePush/CodePush.h> // codepush add this line

#import <React/RCTBridge.h>
...

And change url that react-native uses to read source bundle.

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
  #if DEBUG
    return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
  #else
    return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];  
    // change the line above to the below
    return [CodePush bundleURL];
  #endif
}
  • Edit Info.plist

Now you should add codepush deployment key and http exception domain to Info.plist.

First you should notify your app to which remote repository to access by setting deployment key. Add key CodePushDeploymentKey to your Info.plist and set value for this. The key that you've copied above.

<plist version="1.0">
<dict>
  ...
    <key>CodePushDeploymentKey</key>
    <string>mydeploymentkey</string>
  ...
</plist>

And you should allow HTTPS network access to download app bundle.

<plist version="1.0">
  <dict>
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
        <key>NSExceptionDomains</key>
        <dict>
            <key>codepush.appcenter.ms</key>
            <dict>
                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                <true/>
            </dict>
        </dict>
    </dict>
  ...
  </dict>
</plist>

Finally, your Info.plist will be like below and iOS part of your app is ready to codepush.

<plist version="1.0">
  <dict>
  ...
  <key>CodePushDeploymentKey</key>
  <string>mydeploymentkey</string>
  ...
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
        <key>NSExceptionDomains</key>
        <dict>
            <key>codepush.appcenter.ms</key>
            <dict>
                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                <true/>
            </dict>
            <key>localhost</key>
            <dict>
                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                <true/>
            </dict>
        </dict>
    </dict>
  ...
  </dict>
</plist>

Setting up Android

  • Add codepush.gradleto android/app/build.gradle
...
apply from: "../../node_modules/react-native/react.gradle"
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"
...
  • Edit MainApplication.java.
...
// 1. import codepush package
import com.microsoft.codepush.react.CodePush;
public class MainApplication extends Application implements ReactApplication {
    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
        ...
        // 2. override getJSBundleFile 
        @Override
        protected String getJSBundleFile() {
            return CodePush.getJSBundleFile();
        }
    };
}
  1. Add deployment key to strings.xml

The same key again.

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

4. Actually codepush-fy your app.

You've finished setting your app to access to remote repository on the native side. Now you should tell your react-native code to check version and update itself.

There could be so many scenarios and options, but I'll explain the easiest one.

// Consider it's your root Component
import React from 'react'
import codePush from 'react-native-code-push'

const App = () => (
  <AwesomeWrapper>
    <AwesomeContent />
  </AwesomeWrapper>
)

// set options for codepush.
const codePushOptions = {
  checkFrequency: codePush.CheckFrequency.ON_APP_START,
  installMode: codePush.InstallMode.IMMEDIATE,
}

// wrap your root component with codepush and let this to be registered in index.js
export default codepush(codePushOptions)(App)

In this case, I set checkFrequency, installMode options and just wrapped the root component. But you can trigger version check and update manually with codepush.sync(). You can read about details at codepush api.

5. Push your code!

All settings are done. You can deploy new app bundle with this command.

appcenter codepush release-react -a {username/appname} -d {trackname}
# you should do this at the root directory of your react-native project
# because it read and run commands from your package.json

Top comments (0)