Active Filters: Fastlane

It's another fastlane Friday! In Bite #140 we began looking at fastlane's actions.

We learned how to add actions to our Fastfile and how they can help truly unlock the full power of fastlane. Today we'll check out a few more actions and look at why we might want to use them. Let's get started!

First up is clear_derived_data. This action does what it says on the tin. (We learned about the DerivedData directory and why clearing it can workaround issues in Xcode in Bite #208). Super handy!

Next, it's ensure_xcode_version. This is great when working on a team, (or for our own sanity) to make sure everyone is on the same, known version of Xcode. We can use it like this:

ensure_xcode_version(version: "7.2")

One action that can be quite versatile is update_info_plist. We can specify a .plist path, (perhaps our app's "main" Info.plist), and modify just about anything inside, here's an example for changing the name depending on how we're deploying:

  plist_path: "path/to/Info.plist",
  display_name: "Spaceships-Beta"

Finally, let's look at prompt. This action lets us collect data from the user, and use it within our lanes.

Let's try using it to allow us to enter a changelog each time we upload a build to TestFlight with Pilot:

changelog = prompt(
  text: "Changelog: ",
  multi_line_end_keyword: "END"

pilot(changelog: changelog)

It's another fastlane Friday!

Bitcode is awesome. It lets our users download much smaller versions of our apps, containing only the bits they need to run it on their devices.

Unfortunately, it creates a few challenges for using third-party crash-reporting services.

Not to worry, fastlane has our backs. Today we'll look at a new built-in fastlane action (Bite #140) that can automate all of this.

The issue is that Crashlytics (or any service analyzing our crash logs) needs our dSYM files to convert raw crash logs to ones that containing line numbers and function names and all the other useful information we'll need to actually fix the bug causing the crash.

We'll begin by making sure we have the latest version of fastlane. (A quick gem update fastlane will do the trick).

Then, we'll add a new lane:

lane :refresh_dsyms do
  download_dsyms                  # Download dSYM files from iTunes Connect
  upload_symbols_to_crashlytics   # Upload them to Crashlytics
  clean_build_artifacts           # Delete the local dSYM files

Now we can just run fastlane refresh_dsyms at anytime and everything will be synced up to Crashlytics. Apple seems to recompile our apps at will, and whenever their systems need.

For these reasons, it's probably best to toss this command into a CI server or some other system that will run it once or twice a day.

Support is already in for Crashlytics, Sentry and HockeyApp.

Everything is open source, so we can add support for our own service if needed.

More info about all of this can be found in fastlane's docs, found here.

It's another fastlane Friday! Today we're looking at frameit, an awesome fastlane tool that helps us take our screenshots to the next level. We can display our screenshots on devices, and even add some marketing text. Let's dive in.

We'll start by installing frameit:

gem install frameit

Next we'll need to perform some initial setup. We'll head into our project's directory and run frameit to kick things off:

frameit will guide us through downloading the high quality frame images from Apple's marketing site and moving them into place.

Now, we can run frameit anytime to find all screenshot files and create versions of them placed inside device frames. Neat!

This works great after running snapshot (covered in Bite #110).

As with most fastlane tools, we can create a Framefile.json where we can configure things like texts, fonts, etc. frameit even lets us use .strings files so everything is easily localized!

frameit also supports all of this for OS X apps as well!

More info about frameit can be found at

Code Signing. The very mention of certificates or provisioning profiles can send chills up an iOS engineer's spine.

We've all been there. Just finished up a great first pass at a new feature, or finally ready to submit to the App Store and BAM! We're stopped in our tracks by a confusing error related to code signing.

Today's fastlane Friday is a big one. Yesterday, a new fastlane tool launched. It's called match, and it fixes code signing. Yes, really. Let's do this. πŸš€

Most iOS teams have separate code signing identities for each member. This means most iOS teams have tons of provisioning profiles, probably lots of duplicates, invalid ones, etc.

Adding new devices or renewing certificates can be a huge hassle, and only makes on boarding new team members slower.

With match, we can avoid these issues entirely. match allows us to share one single code signing identity across our development team.

We keep this single identity (and it's associated provision profiles) in one central location.

match automatically syncs our iOS keys and profiles using a simple git repository. It handles everything (i.e. creating certificates and profiles), while we retain complete control.

Let's setup match for a project. We'll start by creating a new Github repository to hold our certificates, profiles, etc.

We'll call it certificates and make absolutely sure it's set to be private!

Then, we'll install match locally:

gem install match

Next, we'll go into our project's main directory and run:

match init

We'll be asked for the URL of the repository we created earlier, then a Matchfile will be created to hold a few settings.

Next we'll run:

match development

match will create a new certificate and provisioning profile, and store them in our Github repo. They'll all be encrypted using openssl! πŸ”

In the future, when we get a new machine for example, we will only need to run that one command to pull down everything and install it all locally. Incredible. Setting up new machines or team members has never been easier (or faster πŸš—πŸ’¨)!

This is only a small taste of how helpful match can be! Check out the incredibly well done complete guide that covers everything from start to finish at

It's another fastlane Friday! Last week in Bite #135, we covered how to install and setup fastlane and an initial Fastfile. Today we'll look at how we can take our fastlane skills to the next level and customize our Fastfile using actions. Let's get started.

We briefly mentioned fastlane actions in Bite #135. Let's start by taking a closer look at them.

Actions are essentially build "steps". fastlane organizes these build steps into sets called lanes. Each action is responsible for a very specific part of the lane's larger task.

Let's add an action to a lane:

lane :beta do

By simply adding the increment_build_number action, we'll never need to manually bump our build number again!

Actions can accept options:

increment_version_number(bump_type: "major")

Or return values:

changelog = prompt(text: "Changelog: ")

There's actions for all of the individual fastlane tools we've covered.

We can install dependencies with actions like carthage and cocoapods. We can deploy with the pilot and deliver actions, or use hockey and crashlytics to upload to those services.

We can notify teammates with slack or archive each release with github_release.

We can even define lanes to bootstrap our dev environment using actions like install_xcode_plugin or dotgpg_environment.

We can "shell out" to a truly custom build script as well:

sh "./"

Simply put, actions are how to get the most out of fastlane. If we're doing something each time we build or deploy, there's a good chance a fastlane already has an action for it.

If not, we can make our own. Just like the Fastfile itself, actions are written in Ruby. We can generate a new one with:

fastlane new_action

Detailed documentation on all actions is available, and we can check out the full list of 120+ actions with:

fastlane actions


#135: Fastlane πŸ€–


It's another fastlane Friday here on LBOC! We've covered a few of the individual fastlane tools so far, but today we'll look at fastlane itself. It gives us a single command that brings together all the various tools in the suite like gym, snapshot, deliver, etc into one streamlined workflow. Let's get started.

We can of course continue to use each of the fastlane tools individually, but using fastlane allows us to use just one tool that connects not only each of the tools in the suite, but also integrates with other third-party tools like CocoaPods and xctool.

fastlane provides a fantastic in-depth Getting Started guide, but to get things going quickly here's the basics:

We'll begin by installing fastlane, this will install all the fastlane tools, including all the ones we've covered here, wrapped into one simple tool.

gem install fastlane

Then, we'll simply run fastlane init in the root directory of our project.

fastlane's setup assistant will ask us a few questions about our app, then it will create all the configuration files for us, where we'll be able to customize each the tools default settings as well as define our β€œlanes”.

After completing the intial setup process, we can start to customize our new Fastfile (which was created for us automatically). fastlane is built around the concept of β€œlanes”. Here's one that deploys to the App Store:

lane :appstore do

We can run all of these tools now, each one after another by simply running fastlane appstore. Nice!

Notice commands like cocoapods and slack are here. These are some of the third-party actions mentioned earlier.

This is where fastlane's awesome community really shines. There's already 120+ actions ready to use for services like s3, slack and crashlytics, as well as commands for things such as bumping the build number, or even collecting input from the user. Neat!

More info about fastlane can be found at

It's another fastlane friday here on LBOC. Today we'll be looking at another awesome tool in the fastlane suite called scan. It provides an easy way to run the tests of our iOS or OS X app. Let's dive in.

Before we begin, let's look at why a tool like scan can be helpful.

Xcode ships with a great command line tool called xcodebuild that allows to do all sorts of interesting things to our projects from the command line. It can be a bit verbose to configure though, and its output isn't very readable at a glance.

There's other tools like xcpretty that can help improve this output, but they take a fair amount of configuration as well.

That's where scan comes in. It takes care of all of this (plus a lot more) in one simple command: scan.

We'll start by installing scan:

gem install scan

Then we run our tests at anytime like this:


This is all we need for basics usage. scan will auto-detect things like our workspace, but we can always configure things as well:

scan --scheme "app-store"

Like other fastlane tools, we can run scan init to generate a new Scanfile, where we can store all our configuration options:

scheme "Spaceships"
clean true
output_types "html"

Other Features

πŸ“ƒ Displays nice output, stores original xcodebuild log in ~/Library/Logs/scan

πŸ“„ Can generate HTML, JSON or JUnit reports

πŸ“£ Can send well-formatted test results to Slack. Check out the slack_only_on_failure configuration option to only report failed tests.

scan also helps with resolving common Xcode oddities like duplicated simulators or simulators that stop responding. Finally, scan works great with tools continuous integration tools like Jenkins and services like Travis. Happy testing!

More info about scan can be found at

Today we're continuing our look at the Fastlane suite of tools with gym. It can help us build and package our app into an .ipa file ready for submission to Apple, or some other kind of distribution. Let's get started.

We'll start by installing gym:

gem install gym

Now we can build and export an ipa like this:


Alright, have a great weekend everyone! Just kidding, while gym is great about asking for answers to things we don't specify such as what Xcode Scheme to use when building. It also allows us to specify just about any option we can imagine when running it on the command line. For example, let's build our app using its Workspace and the app-store scheme:

gym --workspace "Spaceships.xcworkspace" --scheme "app-store" --clean

Simple enough, we're telling gym to build using our desired Workspace and Scheme, and that we'd like to do a clean build.

gym has options for just about everything: bitcode, codesigning, provisioning, team id, and much more. It's extremely flexible but including all those command line options each time can be drag. Let's unlock more of the power of gym by creating what's called a Gymfile in our project's directory. This is just a plain text file, and looks like this:

scheme "Spaceships"
sdk "iphoneos9.0"
clean true

output_directory "./build" # where to put the ipa
output_name "Spaceships"   # what to call the ipa

Now we can run gym again from the command line and we don't need to specify all those options each time, nice! More info about gym can be found at

It's another Fastlane Friday here on LBOC. Today we're looking at deliver, another awesome tool in the Fastlane suite. It can save us tons of time and effort when it comes to uploading our app's metadata, screenshots and binary to iTunes Connect. Let's take it for a spin:

We'll start by installing deliver:

gem install deliver

Then we'll setup deliver for our project by cd'ing into its directory and running:

deliver init

We'll be asked for our iTunes Connect login and then our app's App ID. What happens next it down-right magical .

deliver will download all our app's metadata (name, description, keywords, release notes, icons, etc.), by language, from iTunes Connect as text files. Then it will organize them into text files inside a new metadata directory. Now we can edit these anytime and run deliver to update iTunes Connect with the edited values. Nice!

In addition to our app's metdata, deliver will also download all our app's screenshots (by language and device) and organize them into a new screenshots directory for us. Again, we can change/update them on disk then simply run deliver again and they'll be uploaded to iTunes Connect.

It gets better. Why don't we just do everything at once and update our app's metadata and screenshots, upload its binary and submit it for review all at once? With deliver, all it takes is:

deliver --ipa "Spaceships.ipa" --submit_for_review

Believe it or not, deliver can do even more. We can pass in tons of options for configuring things like automatic release vs. manual, price tiers, add pre-defined answers to all those compliance questions we're asked during submissions, and more. We can also create a Deliverfile to easily reuse our options every time.

More info about deliver can be found at


#114: Creating New Apps with Produce πŸ“


Starting new projects can be incredibly fun. Performing all the tasks that aren't building our app can be incredibly not-so-fun. Today we'll continue our look at the Fastlane suite of tools (from Bite #110) by checking out Produce, a command-line tool for creating and managing apps on iTunes Connect and the Developer Portal. Let's take a look.

Let's make a new app. Before we do though, we'll install produce:

gem install produce

Now, let's create our app, we'll run:


Then we'll be asked for 4 values. We'll enter each when prompted (We could also specify these as arguments to the produce command).

Your Apple ID Username: **hidden**
App Identifier (Bundle ID): com.magnus.littlebitesofcocoa
App Name: Little Bites of Cocoa
Initial version number (e.g. '1.0'): 1.0

Produce will work its magic and when it's done, our app will have been completely created and setup on both iTunes Connect and the Developer Portal. Very cool.


Produce can also help us easily enable (or disable) things like Associated Domains, iCloud, Passbook, etc. Let's enable CloudKit for our app:

produce enable_services --icloud cloudkit -a com.magnus.littlebitesofcocoa

Nice! So much quicker than clicking around the Developer Portal.

App Groups

Last but not least, we'll be creating extensions for app that share data so let's create a new App Group and put our new app into it:

produce group -g group.littlebitesofcocoa -n "Little Bites of Cocoa"
produce associate_group -a com.magnus.littlebitesofcocoa group.littlebitesofcocoa

More info about Produce can be found at

Page 1 of 2