React Native

Deploy your React Native App to the store automatically with Fastlane

Deploying your React Native app to the stores manually can be a painful experience. It is time-consuming, error prone and not beginner-friendly. Fortunately, Fastlane helps you automate the process.

 

This article will explain how to use Fastlane in the specific case of a React Native app. To get started quickly with Fastlane, see this tutorial.

First, we'll need to setup a few things.

Set up your React Native app

Add icons to your app

Apple requires you to have icons for your app, so be sure to have some added to your project. See how to setup your React Native app icons in a single command line.

Set your bundle identifier

Be sure to change your bundle identifier, on the General tab in XCode.

Set bundle identifier

Do not let XCode manage signing

  • On XCode 8 only, in the General tab, deselect Automatically manage signing:
Disable automatic signing
  • For all XCode versions, in the Build Settings tab, under Signing, set iOS developer as the debug codesigning identitiy and iPhone distribution as the release codesigning identitiy.
Set the right codesigning identities

Let the magic begin

Create the Fastlane config

For an easy setup on iOS, cd into the ios folder of your app and run:

++pre>++code>fastlane init
++/code>++/pre>

Fastlane will ask for some info about your app, and automatically create a ++code>fastlane++/code> folder for you.

When asked to confirm the values, answer ++code>n++/code>. Fastlane hasn't guessed your app identifier and needs a little help.

do not confirm values

Then, Fastlane will automatically create your app on the Apple developer member center and iTunes Connect. Neat, isn't it? It can take a few minutes to create it on iTunes Connect.

When asked for a ++code>scheme++/code>, you have to enter the name of your project. For instance, I started my app with ++code>react-native init AwesomeProject++/code>, my scheme name is thus ++code>AwesomeProject++/code>.

fastlane scheme

That's it! You now have a Fastlane configuration folder setup for your app.

You should have an ++code>Appfile++/code> with specific info about your app a bit like:

++pre>app_identifier "tech.bam.alex.fastlane.awesomeproject" # The bundle identifier of your app
apple_id "alexandre@bam.tech" # Your Apple email address

team_id "Z445H6455F"  # Developer Portal Team ID++/pre>

Checkout ++code>ios/fastlane/Fastfile++/code>, you should have a lane for the appstore:

++pre>desc "Deploy a new version to the App Store"
lane :release do
 # match(type: "appstore")
 # snapshot
 gym(scheme: "AwesomeProject") # Build your app - more options available
 deliver(force: true)
 # frameit
end++/pre>

Yes! We're close! You could run it with ++code>fastlane ios release++/code> but we still need to setup match for Codesigning.

Setting up match

Match is awesome for handling your team certificates and your provisioning profiles. It will store them in a private git repo for you. See the fastlane codesigning guide for more info.

Create a private repository for ++code>match++/code> if you haven't done so yet. Bitbucket is a well known free option.

Then change you ++code>release++/code> lane like so:

++pre>desc "Deploy a new version to the App Store"
lane :release do
 # Uncomment match and add git_url
 match(
   type: "appstore",
   # Use your own repository!
   git_url: "https://bitbucket.org/Almouro/awesome-certificates"
 )
 gym(scheme: "AwesomeProject") # Build your app - more options available
 deliver(force: true)
end++/pre>

This setup would now work with XCode 7. But with XCode 8, by running ++code>fastlane ios release++/code>, you would now encounter the dreaded error:

++pre>++code>Code signing is required for product type 'Application' in SDK 'iOS 10.0'
++/code>++/pre>

Handling XCode 8

We have to specifically tell XCode which team and provisioning profile to build your app with.

The easy way

In your deployment lane, uncomment everything but the ++code>match++/code> step to create and retrieve a provisioning profile for your app. Then you can select it in XCode, under the General tab:

manually select provisioning profile

Don't forget to commit the changes to the XCode project!

The code way

We can also select the team and the provisioning profile with code in the ++code>Fastfile++/code>, by adding ++code>xcargs++/code> to ++code>gym++/code>:

++pre>++code>gym(
 scheme: 'MyAwesomeApp',
 xcargs: "PROVISIONING_PROFILE_SPECIFIER='639b81fa-c63e-4127-a4ef-3e2b73de2033' DEVELOPMENT_TEAM='58628H666T'"
)
++/code>++/pre>

Sure, you can find the development team in the ++code>Appfile++/code> but I don't really want to specify the uuid of the provisioning profile. Fortunately, ++code>match++/code> exports an environment variable to retrieve it easily.

Say your app identifier is ++code>com.myawesome.app++/code>, and you're building your app for the ++code>appstore++/code>, then++code>sigh_com.myawesome.app_appstore++/code> will be an environment variable containing your provisioning profile uuid. More info is available on the Fastlane docs

You can then replace above code with:

++pre>++code>gym(
 scheme: 'MyAwesomeApp',
 xcargs: "PROVISIONING_PROFILE_SPECIFIER='#{ENV[\'sigh_com.myawesome.app_appstore\']}' DEVELOPMENT_TEAM='58628H666T'"
)
++/code>++/pre>

To improve that even more, you can actually retrieve values from your ++code>Appfile++/code>, with

++pre>++code># Fetching app identifier
CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier)
++/code>++/pre>

The code now becomes:

++pre>++code>team_id = CredentialsManager::AppfileConfig.try_fetch_value(:team_id)
app_identifier = CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier)
profile = ENV["sigh_#{app_identifier}_appstore"]
gym(
 scheme: 'MyAwesomeApp',
 xcargs: "PROVISIONING_PROFILE_SPECIFIER='#{profile}' DEVELOPMENT_TEAM='#{team_id}'"
)
++/code>++/pre>

Reaping the rewards

You should now have a lane looking more or less like below, depending on which option you chose to handle XCode 8.

++pre>desc "Deploy a new version to the App Store"
lane :release do
 match(
   type: "appstore",
   git_url: "https://bitbucket.org/Almouro/bamlab-certificates"
 )
 sh "printenv"
 team_id = CredentialsManager::AppfileConfig.try_fetch_value(:team_id)
 app_identifier = CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier)
 profile = ENV["sigh_#{app_identifier}_appstore"]
 sh "echo sigh_#{app_identifier}_appstore"
 gym(
   scheme: 'AwesomeProject',
   xcargs: "PROVISIONING_PROFILE_SPECIFIER='#{profile}' DEVELOPMENT_TEAM='#{team_id}'"
 )
 deliver(force: true)
end++/pre>

Run

++pre>++code>fastlane ios release
++/code>++/pre>

And reap the rewards!

itunes build successful

Anyone on your team can now use this command to deploy to the app store.

You can now select your build in iTunes Connect and submit it for review.

Automate all the things

At BAM, we regularly start new projects. We feel like this setup is still pretty long, checkout the Yeoman generator we built to do those steps for you!

 

Questions, comments?

If you have questions, comments, or any issue on this tutorial, feel free to use the comment section below! ;)

Développeur mobile ?

Rejoins nos équipes