Simplify the Process of Uploading iOS dSYM Files to Crashlytics with Fastlane

Header image from Firebase blog titled Simplify the process of uploading iOS dSYM files to Crashlytics by using fastlane
Header image from Firebase blog titled Simplify the process of uploading iOS dSYM files to Crashlytics by using fastlane

We’ve heard your feedback about the challenges you’ve experienced when uploading dSYMs to Crashlytics, especially for apps with bitcode enabled. We’re working to improve this process and wanted to share a way to automate it by using fastlane.

The automated process

The current process

When building apps without bitcode, the Crashlytics upload-symbols tool that you include as a run script automatically uploads your app’s dSYM files every time you rebuild your app. When the app sends us crash reports, these files allow us to symbolicate the stack frames included in the reports so that you see source code rather than compiled code on the Crashlytics dashboard.

However, for apps with bitcode enabled, the process of uploading dSYMs isn’t automatic. Instead, you need to download updated dSYMs from Apple and upload them manually to Crashlytics each time you submit a new version of the app to App Store Connect.

This manual process can be a pain especially since non-technical team members are often responsible for uploading bitcode dSYMs.With fastlane, you can use a single command to automatically download and upload your bitcode dSYMs.

What is fastlane?

Fastlane is an open-source tool that automates the build and release workflow for iOS and Android apps, including tasks like code signing and generating screenshots. See the official fastlane documentation for more information.

There are a couple of fastlane tools that will help you automate the process of uploading dSYMs to Crashlytics: actions, lanes, and Fastfiles.

An action is one of the building blocks of fastlane. Each action performs a single command, such as running tests or performing code validation.

One or more actions can be included in a lane. You can think of a lane as a workflow that is (usually) composed of related tasks. For this Crashlytics workflow, the lane will consist of three actions: downloading dSYMs from Apple, uploading dSYMs to Crashlytics, then cleaning up the files. Each lane also has a name and description.

And finally, a Fastfile manages the lane created in this workflow, as well as any others you use for your project.

Configure fastlane with Crashlytics

Setting up fastlane

You can set up fastlane in multiple ways, including with Bundler and Homebrew. For instructions, see fastlane’s Getting Started for iOS guide. During the fastlane init step, make sure to choose the manual setup option.

Once fastlane is set up, the first step toward automating symbol uploads is configuring a lane. We’ll do this by editing the Fastfile that was created in the fastlane directory during the setup step. Let’s start by modifying the default lane, which currently looks like this:

desc "Description of what the lane does"
lane :custom_lane do
  # add actions here: https://docs.fastlane.tools/actions
end

For the desc field, we’ll include a brief summary of the lane’s purpose:

desc "Downloads dSYM files from Apple for a given app version and uploads them to Crashlytics"

And then give the lane a name:

lane :upload_symbols do

Adding actions to a lane

Next, we’ll add actions to our lane. There are three actions that we’ll use: download_dsyms,

upload_symbols_to_crashlytics, and clean_build_artifacts. (For fastlane’s documentation on any of these commands, run fastlane action command_name in your terminal.)

download_dsyms will do the work of downloading the new dSYM files from Apple. We’ll just need to provide the action with either 1) the version number and build for the app version that you want to download dSYMs for or 2) the live and latest version constants to download the live or latest version’s dSYMs, respectively. Optionally, you can also specify your app’s bundle ID and your App Store Connect username to avoid having to enter them manually when you run the action. All in all, this action will look similar to one of the following:

  • Specific version and build, specifying bundle ID, but no App Store Connect username: download_dsyms(version: "1.0.0", build_number: "1.0.0", app_identifier: "bundleID")
  • Live version, no App Store Connect username or app bundle ID: download_dsyms(version: "live")
  • Latest version, specifying bundle ID and App Store Connect username: download_dsyms(username: "username", version: "latest", app_identifier: "bundleID")

In this guide, we’ll use the last option (i.e, latest version, specifying both bundle ID and App Store Connect username).

upload_symbols_to_crashlytics will take the files from download_dsyms and upload them to Crashlytics. This command takes as a parameter the GoogleService-Info.plist file for the app, like so:
upload_symbols_to_crashlytics(gsp_path: "path/to/GoogleService-Info.plist")

Note: If you’re using Swift Package Manager (instead of CocoaPods), you’ll need to download the Crashlytics upload-symbols tool, place it in your project directory, make it executable (chmod +x upload-symbols), then set the binary_path variable in the upload_symbols_to_crashlytics action: upload_symbols_to_crashlytics(gsp_path: "path/to/GoogleService-Info.plist", binary_path: "upload-symbols").

Delete dSYM files once they’ve been uploaded

Lastly, we’ll use clean_build_artifacts to delete the dSYM files once they’ve been uploaded.

Our lane now looks something like this:

desc "Downloads dSYM files from Apple for a given app build and version and uploads them to Crashlytics"
lane :upload_symbols do
  download_dsyms(username: "username", version: "latest", app_identifier: "bundleID")
  upload_symbols_to_crashlytics(gsp_path: "path/to/GoogleService-Info.plist")
  clean_build_artifacts
end

(If you’re using Swift Package Manager, the only difference will be the binary_path variable in the upload_symbols_to_crashlytics action.)

And here’s our Fastfile with just this one lane:

default_platform(:ios)

platform :ios do
  desc "Downloads dSYM files from Apple for a given app version and uploads them to Crashlytics"
  lane :upload_symbols do
    download_dsyms(username: "username", version: "latest", app_identifier: "bundleID")
    upload_symbols_to_crashlytics(gsp_path: "path/to/GoogleService-Info.plist")
    clean_build_artifacts
  end
end

To run this lane, run fastlane upload_symbols from the terminal inside your project folder (replace upload_symbols if you chose a different name for the lane). You’ll be asked to log into your App Store Connect account (and select your App Store Connect team, if you have more than one associated with your account). If needed, you can customize the actions in the file to include more information about your account to avoid having to log in manually.

What’s next?

Get started with fastlane and start automating your dSYM uploads!

We’re always looking for ways to make Crashlytics work better for developers. We want to thank everyone who has provided us with feedback on GitHub, Firebase Support, and other channels about the dSYM upload process, and we encourage you to continue to reach out with questions and suggestions!