Photo by Daniel Monteiro on Unsplash

Get your iOS project on the fastlane with match & Firebase App Distribution

Marsel Tzatzo
Firebase Developers
6 min readFeb 4, 2020

--

On the previous article we talked about using multiple configurations so that we have multiple versions of our app looking at different environments. The cool about this is that we can simultaneously have our dev, stage & production version of our app installed on the device. We also configured then to have different names, app icons and different widgets for our app.

So, what comes next after project setup is automation. We would like to automate our build & distribute process. This of course can be done via a CI/CD tool such as Jenkins, nonetheless whatever can be done at a server can also be done locally. Fastlane is a collection of tools that automate your builds and provide some CLI tools in order to upload your builds to services such as Firebase or App Store.

Fastlane consists of a set of tools that will help us in various ways. Combined with a CI/CD tool you get a complete automation suite for your iOS project. Fastlane also supports Android. You can check my Android fastlane guide here.

This article might be long but at the end of this article you will be able to

  1. Run tests for your project
  2. Automagically manage your certificates and provisioning profiles
  3. Build, upload your project’s dev version to Firebase and notify your testers

First thing you need is fastlane, and you can find instructions on how to install it here.

Now let’s setup fastlane for our project. Open a terminal, go to your projects directory and type

fastlane init

A question will ask you what will you use fastlane for, type 4 and hit enter. We are going to setup fastlane on our own:

[15:39:19]: What would you like to use fastlane for?
1. 📸 Automate screenshots
2. 👩‍✈️ Automate beta distribution to TestFlight
3. 🚀 Automate App Store distribution
4. 🛠 Manual setup - manually setup your project to automate your tasks
? 4

Now you should be seeing a new folder called fastlane. This folder currently has twofiles, a Fastfile & an Appfile. We are going to edit them shortly, but first let explain what these files are.

Fastfile is the one that we are going to write our lanes in. Lanes are the functions we will be writing such as the test and the build & upload function.

Appfile is a helper file and we are going to keep some configuration in that file, such as the application identifier, configuration etc. Storing this information there is easy to retrieve it from within our lanes.

I suggest you stick to this for now, and as soon as you finish this tutorial go to the links provided and read more about Fastfile and Appfile.

Before anything else we would like to setup our unit testing. To do so we will be using fastlane scan. Scan is just a wrapper for a tool called run_tests, and has some niche features. Go back to your terminal and type fastlane scan init. A new file will be generated, the Scanfile. This is where our testing configuration will reside. Now replace its content with the following:

skip_build(true)
scheme("Debug-Development") # Or whatever your debug scheme is
output_types("html") # The output of our tests will be in html
devices(["iPhone 11"]) # You can add as many as you like here

Once done, run fastlane scan. You should be seeing an output and at the end of it will be the result your tests. You can find all the available parameters for the scan action here.

+--------------------+---+
| Test Results |
+--------------------+---+
| Number of tests | 2 |
| Number of failures | 0 |
+--------------------+---+

Scan will also output a report in HTML (JSon or JUnit). Notice there is a new folder generated by scan which has the content of your scan report nicely presented in HTML format, like below.

Test results html

So, now that we finished our unit test “lane” setup, we are going to write a lane to build our app and distribute it via Firebase App Distribution (formerly Fabric Beta). I am using the word lane for the scan action we used even though we haven’t written a lane yet.

Is it built. Almost…

We are almost there… In order to build and distribute your app you must first create your distribution certificate provisioning profiles etc. Well that laborious task can be avoided if you decide to go with fastlane match.

We are going to use a git repo (private or public, doesn’t really matter) to store our certificate and our provisioning profiles, and match will be doing all the management and will keep them in sync. If you have any concerns about storing your .p12 and provisioning profiles on a public repository then read this. There is an initial setup that will take 5~10 mins but afterwards you can stop worrying about certificate management.

We will be using git to store our certificates, so we need a fresh repository. Head to favourite version control system (Github, Bitbucket etc.) and create a fresh repository.

Go back to your console again and type

fastlane match init

You will be prompted to chose either git or google_cloud as your storage provider (select 1 — git), and in the next prompt paste the link to the repository you just created.

Match is set and now all we got to do is create a set of adhoc provisioning profiles for our adhoc builds. Match will create the needed certificate & provisioning profile and will add it to our keychain, and will also add them to our repository.

fastlane match adhoc

We are done for now with match.

Can we build now? Not yet…

We need to add the Firebase App Distribution plugin before we build. On your terminal, inside your projects folder, type

fastlane add_plugin firebase_app_distribution

This will install the firebase plugin, create a Pluginfile with the firebase_app_distribution plugin installation instructions, and will also reference the plugin file from your Gemfile. So when you will bundle install on another machine, the plugin will also be installed. Now install the firebase cli by typing

curl -sL https://firebase.tools | bash

Now run firebase login and you are ready to go.

Note: You won’t be able to use Firebase unless you login.

Note 2: I am skipping the part where you need to open your Firebase console, create a new project and add a new app on it.

Ok, it’s about time we build this thing

Open your Fastfile and paste the following. I will explain what the following does shortly.

desc "Builds Release-Development & uploads to Firebase App Distribution"
lane :app_distribution do
match(type: 'adhoc', app_identifier: ['com.max.MyAwesomeApp.dev', 'com.max.MyAwesomeApp.dev.widget'])gym(
project: 'MyAwesomeApp.xcodeproj',
scheme: 'Release-Development',
configuration: 'Release-Development',
clean: true,
output_directory: 'archives',
output_name: 'MyAwesomeApp.development.ipa',
export_method: 'ad-hoc'
)
firebase_app_distribution(
app: 'your_app_id',
testers: ['list','of','testers','to', 'invite'],
release_notes: 'some release notes',
firebase_cli_path: '/usr/local/bin/firebase',
ipa_path: 'archives/MyAwesomeApp.development.ipa'
)
end

Let’s break this down a little bit. First we use match

match(type: 'adhoc', app_identifier: ['com.max.MyAwesomeApp.dev', 'com.max.MyAwesomeApp.dev.widget'])

What this will do is that if we move to another machine, fastlane match will manage and install the certificates and provisioning needed for our project for us. All we got to do is provide the credentials to our developer account. Next comes gym which is an alias to build_app. I will get into more details about gym, on my next article, where i will be continuing this article with the upload to Testflight.

gym(
project: 'MyAwesomeApp.xcodeproj',
scheme: 'Release-Development',
configuration: 'Release-Development',
clean: true,
output_directory: 'archives',
output_name: 'MyAwesomeApp.development.ipa',
export_method: 'ad-hoc'
)

Gym builds our project and saves our .ipa and .dsym files in the archives directory (output_directory) which will be created at the top level directory of our project. The name of our ipa will be the output_name provided above.

firebase_app_distribution(
app: 'your_app_id',
testers: ['list','of','testers','to', 'invite'],
release_notes: 'some release notes',
firebase_cli_path: '/usr/local/bin/firebase',
ipa_path: 'archives/MyAwesomeApp.development.ipa'
)

Last, we need to upload our build and distribute to our testers, clients or friends. This is what firebase_app_distribution does. You can find your app id in the Firebase console, under your project’s Apps tab. Keep in mind that every app (Apple identifier) has its own app id. ipa_path is the path of the output that gym produced during our build.

Finally, hit and wait.

app_distribution

If everything goes according to plan, your testers will receive an email and will be able to install your app.

On the next article of this series I will be using fastlane to build the production version of the app and upload it to Testflight connect. I will also use the scan command we set here.

Thanks for time! I hope you find this article useful.

--

--