Getting Started with Fastlane for iOS

Fastlane is an incredibly powerful tool for mobile developers. Using fastlane can save you time running tests, creating builds, supporting continuous integration and many other tasks that can be a hassle to deal with as a mobile developer. In this post I’ll take you through a quick setup of deploying an iOS app to Fabric Beta as well as running unit tests.

Install Fastlane

Fastlane can be installed with ruby gems or homebrew.

sudo gem install fastlane -NV
brew cask install fastlane

Start using Fastlane

Project Setup

In your root project directory, run:

fastlane init

After a few moments you will see something similar to this

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

Fastlane has some good defaults set up, but let’s start a Manual Setup for now. Choose 4 and press enter. After hitting enter a few more times you can open the Fastlane folder with your editor of choice. In this directory you’ll see a file called Fastfile, this is where the bulk of the work will be done.

Unit Test Lane

Our first lane is very simple and works with Fastlane right out of the box.

desc "Run Tests"
lane :test do
    run_tests(
        workspace: '{{YourWorkspace}}.xcworkspace',
        scheme: '{{YourScheme}}',
        devices: ['iPad Air 2', '{{Other devices}}']
    )
end

This uses the run_tests action provided by Fastlane.

The Beta Lane

We’ll build our next lane piece by piece to better understand what’s going on in each action.

Registering Devices

One of the things that Fastlane makes super convenient is registering devices to your provisioning profile when you’re using fabric. If you’ve used this in the past you know how time consuming it can be. I keep a devices.txt file in the root directory or the project and update it as I get emails from fabric for new devices and testers. We can use the following to register the new devices before sending a build.

register_devices(
    team_id: '{{YourTeamId}}',
    devices_file: './devices.txt'
)

Provisioning Profile and Certificate

There are a few ways to deal with provisioning and certificates using Fastlane, I will go over one of the methods but there are other great options here that you should absolutely check out. For teams with multiple developers creating builds I would recommend using match. It takes a little more time to setup but is well worth it in the long run. Anyway, here is what we’re going to use for now.

get_certificates(
    team_id: '{{YourTeamId}}'
)
 
get_provisioning_profile(
    team_id: '{{YourTeamId}}',
    adhoc: true,
    app_identifier: '{{YourAppIdentifier}}'
)

Let’s Build This Thing! ?‍♀️

build_app(
    workspace: '{{YourWorkspace}}.xcworkspace',
    scheme: '{{YourScheme}}',
    include_symbols: true,
    export_xcargs: '-allowProvisioningUpdates',
    export_method: 'ad-hoc'
)

Send To Fabric AKA Crashlytics

crashlytics(
    api_token: '{{YourApiToken}}',
    build_secret: '{{YourBuildSecret}}'
)

A Few Improvements

If you are running this locally you can easily hardcode the parameters. Since this is most likely not your situation it is beneficial to take advantage of passing in options. These can be build numbers from your CI Server, stored usernames, app ids… you name it. To set this up simply add |options| to your lane definition.

lane :beta do |options|

Now you can use any parameter you like. Here’s our final lane with options:

desc "Send a build to Fabric beta"
lane :beta do |options|
    if options[:skip_testing] != true
        test # call the test lane
    end
 
    increment_build_number(
        build_number: options[:build_number]
    )
 
    register_devices(
        team_id: options[:team_id],
        devices_file: './devices.txt'
    )
 
    get_certificates(
        team_id: options[:team_id]
    )
 
    get_provisioning_profile(
        team_id: options[:team_id],
        adhoc: true,
        app_identifier: options[:app_id]
    )
 
    build_app(
        workspace: '#{options[:workspace]}.xcworkspace',
        scheme: options[:scheme],
        include_symbols: true,
        export_xcargs: '-allowProvisioningUpdates',
        export_method: 'ad-hoc'
    )
 
    crashlytics(
        api_token: '',
        build_secret: ''
    )
end

Finishing Up

You’ll notice that in your initial setup, fastlane gave you an Appfile to compliment your Fastfile. You can set variables like app identifier and username in here, but I would recommend you don’t add any passwords. These can be setup in your CI server by passing them as the environment variable FASTLANE_PASSWORD. If you are running locally you’ll be prompted to enter your password on the command line, it will be saved for future local runs by Fastlane.

Thats all for now. I hope this kickstarts your build process and interest in Fastlane. For all that Fastlane can do visit: https://docs.fastlane.tools/actions

Questions or Corrections? Let me know in the comments.

About the Author

Elvin Bearden profile.

Elvin Bearden

Sr. Consultant

Elvin has experience in Swift, Objective-C, Java, PHP and restful API’s. He has spent 5 years developing native iOS applications in a variety of fields. When not working on iOS, Elvin enjoys playing guitar, listening to music, playing video games and reading.

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Blog Posts
Android Development for iOS Developers
Android development has greatly improved since the early days. Maybe you tried it out when Android development was done in Eclipse, emulators were slow and buggy, and Java was the required language. Things have changed […]
Add a custom object to your Liquibase diff
Adding a custom object to your liquibase diff is a pretty simple two step process. Create an implementation of DatabaseObject Create an implementation of SnapshotGenerator In my case I wanted to add tracking of Stored […]
Keeping Secrets Out of Terraform State
There are many instances where you will want to create resources via Terraform with secrets that you just don’t want anyone to see. These could be IAM credentials, certificates, RDS DB credentials, etc. One problem […]
Validating Terraform Plans using Open Policy Agent
When developing infrastructure as code using terraform, it can be difficult to test and validate changes without executing the code against a real environment. The feedback loop between writing a line of code and understanding […]