How to Deliver a React Native App to the Client

May 10, 2018 0 Comments

How to Deliver a React Native App to the Client



If you have written some React Native apps, you’ve probably noticed that the process of beta-release version generation requires many repeatable steps to be taken, especially for multiplatform apps.

Let’s look at sample action steps you need to perform to deliver the beta version app to the client or tester:

  1. Download the proper branch from the repository
  2. Insert APK signing key into the ./android/app/ directory
  3. Build the release version
  4. Send the app, e.g. via e-mail
  5. Launch Xcode
  6. Change the scheme to Release
  7. Change the jsCodeLocation value to a static main.jsbundle file path
  8. Archive
  9. Upload the app to TestFlight

As you can see, the above list consists of a large number of repeatable steps. Since they are repeatable, we can automate them, right?

Possible solutions

There are several solutions for automating beta release version generation and delivering the app to the client.

Visual Studio App Center

The first solution that came to our minds at Brainhub was the use of the Visual Studio App Center. A project built by Microsoft seems to be really attractive – apart from building the app in the cloud (free 240 minutes / month of building), distribution among testers and the client, it also provides a platform for testing apps on many real devices, giving access to reports and screenshots of every step of the process.

However, it quickly turned out that this is not the appropriate solution for our project. VS App Center has limited configuration abilities and the app’s code needs to be downloaded from git repository hosted on GitHub, Bitbucket or VSTS. Due to the fact that we use GitLab, we had to rule out this solution.

HockeyApp and Fastlane

The next option was to use HockeyApp – a tool for app distribution, collecting crash reports and users’ feedback. The service was initially created for distribution of iOS apps using the ‘ad hoc’ method (outside of App Store), but currently it works for Android also.

HockeyApp works well as a delivery platform of software testing versions but does not give the functionality of building the app. However, we can use Fastlane – a tool for mobile app building process automation built by


Before you start building and deploying the app, you should prepare the environment. This section describes the steps you should take first.

Automatic jsCodeLocation change

React Native documentation says that you should change jsCodeLocation to static js bundle for the iOS release version in AppDelegate.m file. But there’s no need to do that manually every time you release the app – you can use #ifdef DEBUG macro to do it automatically. Just replace the line containing jsCodeLocation = ... with the following code.

#ifdef DEBUG // DEV jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; #else // PROD jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif

Ignore helper files

During the process of building the app, there will be some helper files created. There’s no need to commit them to the repository, so just add them to the following to .gitignore file.

# Deployment *.cer *.jsbundle *.jsbundle.meta * *.keystore *.mobileprovision fastlane/report.xml

APK signing key

To release an Android, app you need a signing key. To learn more about this process, look here.
When you have your key generated, move it to the android/app directory and remember to add *.keystore to .gitignore.

Fastlane + HockeyApp + Testflight

In this section, you will learn how to automatically generate an app written in React Native for Android and iOS platforms and send it to HockeyApp (Android) and Testflight (iOS).

First, let’s install Fastlane. Make sure you have the newest version of Xcode command line tools installed.

$ xcode-select --install

Install Fastlane.

$ [sudo] gem install fastlane -NV` or `brew cask install fastlane`

Init Fastlane.

$ fastlane init

The command above will create the fastlane directory in current directory with a file called Fastfile that contains the Fastlane configuration.


In the fastlane directory, create a file called Appfile, which stores data that is used across all fastlane tools, e.g. AppleID. It is required for the iOS build and deployment to Testflight.

Add your AppleID to the Appfile.

apple_id ""


Beta release Fastfile might look like this.

# More documentation about how to customize your build # can be found here: # # fastlane_version "2.68.0" # Fastfile actions accept additional configuration, but # don't worry, fastlane will prompt you for required # info which you can add here later platform :ios do lane :beta do ensure_git_branch( branch: "master" ) git_pull increment_build_number( xcodeproj: "./ios/yourProject.xcodeproj" ) get_certificates get_provisioning_profile( app_identifier: "" ) # build your iOS app build_ios_app( project: "./ios/yourProject.xcodeproj", scheme: "yourProjectRelease", export_method: "app-store" ) # TestFlight pilot() end end platform :android do lane :beta do ensure_git_branch( branch: "master" ) git_pull # build the release variant gradle(task: "clean", project_dir: "android/") gradle(task: "assemble", build_type: "Release", project_dir: "android/") # upload to HockeyApp hockey( api_token: "YOUR_TOKEN" ) end end

Let’s analyze our Fastfile step by step.

The code block below will be executed after typing fastlane ios beta into the console.

platform :ios do lane :beta do # ... end end

Similarly for Android – fastlane android beta.

platform :android do lane :beta do # ... end end

Ensure that the current branch is master and perform git pull to sync with the remote repository.

ensure_git_branch( branch: "master" ) git_pull

Let’s increment the build number (works for iOS only). The application that is being sent to Testflight has to have a higher build number than the previous version.

increment_build_number( xcodeproj: "./ios/yourProject.xcodeproj" )

Testflight and Ad Hoc distribution require the proper certificate and provisioning profile. There are several methods of signing apps:

  • match,
  • cert and sigh,
  • Xcode’s code signing feature,
  • manually.

In this article, cert and sigh was used. For further reading about codesigning using Fastlane, visit this site.

get_certificates get_provisioning_profile( app_identifier: "" )

Next, there is the step of building the iOS version where we pass the params such as project path, scheme and export_method (one of the following values: app-store, ad-hoc, package, enterprise, development, developer-id).

build_ios_app( project: "./ios/yourProject.xcodeproj", scheme: "yourProjectRelease", export_method: "app-store" )

The last step regarding iOS is sending the app to Testflight.


Now let’s look at the Android version. There are two gradle steps: cleaning and building release version.

gradle(task: "clean", project_dir: "android/") gradle(task: "assemble", build_type: "Release", project_dir: "android/")

Now you can send the generated app to HockeyApp.

hockey( api_token: "YOUR_TOKEN" )

It is worth mentioning that even if you forget to add some parameter or do it intentionally, e.g. no iTunes Connect user in Fastfile Fastlane will ask you for that data in the console.

HockeyApp Configuration

After signing up and signing in to HockeyApp, you will see the blue “New App” button.

After pressing that button, you will see a dialog box. Choose “Create the app manually instead” option.

On the next screen, you can add application data such as “CFBundleIdentifier” from the Info.plist file for iOS and “package” from AndroidManifest.xml for Android. Based on this value, HockeyApp will connect the uploaded app with the app that you are now creating in the HockeyApp.

After saving the data, HockeyApp will show you the application screen. You can invite users to test the app from there. After accepting the invitation, they will get notifications about every new version of the app.

Let’s navigate to the user settings to generate the token that is needed for sending apps with Fastlane.

Paste the token to Fastfile.

hockey( api_token: "token_goes_here" )

Testflight Configuration

After signing up and signing in to iTunes Connect, you have to create a new application. Choose one of the certificates that you are using to sign the app in the Bundle ID field. If you don’t have the click Register a new bundle Id on the Developer label, create a certificate and choose it in the Bundle ID field.

Create App Store and Ad Hoc certificate.

Running the script

Now you are ready to build and upload the app to HockeyApp and Testflight.

$ fastlane ios beta && fastlane android beta

If you are getting the error: [Transporter Error Output]: Could not start delivery: all transports failed diagnostics it means that your computer is behind the firewall that blocks ports required by Aspera or Signiant protocols used by iTunes Connect Transporter.

In that case, you should use the DAV protocol which is an extension of HTTP. To do that, add the following flag before the following command.

$ DELIVER_ITMSTRANSPORTER_ADDITIONAL_UPLOAD_PARAMETERS=\"-t DAV\" fastlane beta && fastlane android beta

After executing the command, Fastlane will inform you about steps that are being performed.

In the steps get_certificates, get_provisioning_profile, pilot, you will be asked for your AppleID if you haven’t pasted it into the Appfile.

After successful Testflight submission, Fastlane will build and send the Android version to HockeyApp.


Do you remember the 9 repeatable steps from the beginning of this article? If not I’ll remind you:

  1. Download the proper branch from the repository
  2. Insert APK signing key into the ./android/app/ directory
  3. Build the release version
  4. Send the app, e.g. via e-mail
  5. Launch Xcode
  6. Change the scheme to Release
  7. Change the jsCodeLocation value to a static main.jsbundle file path
  8. Archive
  9. Upload the app to TestFlight

After completing this tutorial, the only step you have to perform is running Fastlane.

There are several tools for the automation of React Native app generation and distribution process on the market. If you don’t need to build the app in the cloud and want to have the whole process under your control, Fastlane with services like HockeyApp, Crashlytics, Google Play, Testflight, etc., should help you achieve that.


Tag cloud