Easily build and sign your app (via gym)



What's gym?


gym is a replacement for shenzhen.

Before gym

xcodebuild clean archive -archivePath build/MyApp \
                         -scheme MyApp
xcodebuild -exportArchive \
           -exportFormat ipa \
           -archivePath "build/MyApp.xcarchive" \
           -exportPath "build/MyApp.ipa" \
           -exportProvisioningProfile "ProvisioningProfileName"

With gym

fastlane gym

Why gym?

gym uses the latest APIs to build and sign your application which results in much faster build times.

Gym Features
🚀 gym builds 30% faster than other build tools like shenzhen
🏁 Beautiful inline build output
📖 Helps you resolve common build errors like code signing issues
🚠 Sensible defaults: Automatically detect the project, its schemes and more
🔗 Works perfectly with fastlane and other tools
📦 Automatically generates an ipa and a compressed dSYM file
🚅 Don't remember any complicated build commands, just gym
🔧 Easy and dynamic configuration using parameters and environment variables
💾 Store common build settings in a Gymfile
📤 All archives are stored and accessible in the Xcode Organizer
💻 Supports both iOS and Mac applications




fastlane gym


fastlane gym --workspace "Example.xcworkspace" --scheme "AppName" --clean


DEVELOPER_DIR="/Applications/" fastlane gym

For a list of all available parameters use

fastlane action gym

If you run into any issues, use the verbose mode to get more information

fastlane gym --verbose


fastlane gym --export_method ad-hoc

To pass boolean parameters make sure to use gym like this:

fastlane gym --include_bitcode true --include_symbols false

To access the raw xcodebuild output open ~/Library/Logs/gym


Since you might want to manually trigger a new build but don't want to specify all the parameters every time, you can store your defaults in a so called Gymfile.

Run fastlane gym init to create a new configuration file. Example:




output_directory("./build")    # store the ipa in this folder
output_name("MyApp")           # the name of the ipa file

Export options

Since Xcode 7, gym is using new Xcode API which allows us to specify export options using plist file. By default gym creates this file for you and you are able to modify some parameters by using export_method, export_team_id, include_symbols or include_bitcode. If you want to have more options, like creating manifest file for app thinning, you can provide your own plist file:


or you can provide hash of values directly in the Gymfile:

  method: "ad-hoc",
  manifest: {
    appURL: " App.ipa",
  thinning: "<thin-for-all-variants>"

Optional: If gym can't automatically detect the provisioning profiles to use, you can pass a mapping of bundle identifiers to provisioning profiles:

  scheme: "Release",
  export_options: {
    method: "app-store",
    provisioningProfiles: { 
      "com.example.bundleid" => "Provisioning Profile Name",
      "com.example.bundleid2" => "Provisioning Profile Name 2"


For the list of available options run xcodebuild -help.

Setup code signing

Automating the whole process

gym works great together with fastlane, which connects all deployment tools into one streamlined workflow.

Using fastlane you can define a configuration like

lane :beta do
  gym(scheme: "MyApp")

# error block is executed when a error occurs
error do |lane, exception|
    # message with short human friendly message
    message: exception.to_s, 
    success: false, 
    # Output containing extended log output
    payload: { "Output" => exception.error_info.to_s } 


You can then easily switch between the beta provider (e.g. testflight, hockey, s3 and more).

How does it work?

gym uses the latest APIs to build and sign your application. The 2 main components are


To build the archive gym uses the following command:

set -o pipefail && \
xcodebuild -scheme 'Example' \
-project './Example.xcodeproj' \
-configuration 'Release' \
-destination 'generic/platform=iOS' \
-archivePath '/Users/felixkrause/Library/Developer/Xcode/Archives/2015-08-11/ExampleProductName 2015-08-11 18.15.30.xcarchive' \
archive | xcpretty


gym automatically chooses a different packaging method depending on the version of Xcode you're using.

Xcode 7 and above

/usr/bin/xcrun path/to/ -exportArchive \
-exportOptionsPlist '/tmp/gym_config_1442852529.plist' \
-archivePath '/Users/fkrause/Library/Developer/Xcode/Archives/2015-09-21/App 2015-09-21 09.21.56.xcarchive' \
-exportPath '/tmp/1442852529'

gym makes use of the new Xcode 7 API which allows us to specify the export options using a plist file. You can find more information about the available options by running xcodebuild --help.

Using this method there are no workarounds for WatchKit or Swift required, as it uses the same technique Xcode uses when exporting your binary.

Note: the script wraps around xcodebuild to workaround some incompatibilities.

Use 'ProvisionQL' for advanced Quick Look in Finder

Install ProvisionQL.

It will show you ipa files like this: img/actions/QuickLookScreenshot-App.png

Supported platforms ios, mac
Author @KrauseFx
Returns The absolute path to the generated ipa file

4 Examples

build_ios_app(scheme: "MyApp", workspace: "MyApp.xcworkspace")
  workspace: "MyApp.xcworkspace",
  configuration: "Debug",
  scheme: "MyApp",
  silent: true,
  clean: true,
  output_directory: "path/to/dir", # Destination directory. Defaults to current directory.
  output_name: "my-app.ipa",       # specify the name of the .ipa file to generate (including file extension)
  sdk: "iOS 11.1"        # use SDK as the name or path of the base SDK when building the project.
gym         # alias for "build_ios_app"
build_app   # alias for "build_ios_app"


Key Description Default
workspace Path to the workspace file
project Path to the project file
scheme The project's scheme. Make sure it's marked as Shared
clean Should the project be cleaned before building it? false
output_directory The directory in which the ipa file should be stored in .
output_name The name of the resulting ipa file
configuration The configuration to use when building the app. Defaults to 'Release' *
silent Hide all information that's not necessary while building false
codesigning_identity The name of the code signing identity to use. It has to match the name exactly. e.g. 'iPhone Distribution: SunApps GmbH'
skip_package_ipa Should we skip packaging the ipa? false
include_symbols Should the ipa file include symbols?
include_bitcode Should the ipa file include bitcode?
export_method Method used to export the archive. Valid values are: app-store, ad-hoc, package, enterprise, development, developer-id
export_options Path to an export options plist or a hash with export options. Use 'xcodebuild -help' to print the full set of available options
skip_build_archive Export ipa from previously built xcarchive. Uses archive_path as source
skip_archive After building, don't archive, effectively not including -archivePath param
build_path The directory in which the archive should be stored in
archive_path The path to the created archive
derived_data_path The directory where built products and other derived data will go
result_bundle Should an Xcode result bundle be generated in the output directory false
result_bundle_path Path to the result bundle directory to create. Ignored if result_bundle if false
buildlog_path The directory where to store the build log *
sdk The SDK that should be used for building the application
toolchain The toolchain that should be used for building the application (e.g., org.swift.30p620160816a)
destination Use a custom destination for building the app
export_team_id Optional: Sometimes you need to specify a team id when exporting the ipa file
xcargs Pass additional arguments to xcodebuild for the build phase. Be sure to quote the setting names and values e.g. OTHER_LDFLAGS="-ObjC -lstdc++"
xcconfig Use an extra XCCONFIG file to build your app
disable_xcpretty Disable xcpretty formatting of build output
xcpretty_test_format Use the test (RSpec style) format for build output
xcpretty_formatter A custom xcpretty formatter to use
xcpretty_report_junit Have xcpretty create a JUnit-style XML report at the provided path
xcpretty_report_html Have xcpretty create a simple HTML report at the provided path
xcpretty_report_json Have xcpretty create a JSON compilation database at the provided path
analyze_build_time Analyze the project build time and store the output in 'culprits.txt' file
xcpretty_utf Have xcpretty use unicode encoding when reporting builds
skip_profile_detection Do not try to build a profile mapping from the xcodeproj. Match or a manually provided mapping should be used false

* = default value is dependent on the user's system

Lane Variables

Actions can communicate with each other using a shared hash lane_context, that can be accessed in other actions, plugins or your lanes: lane_context[SharedValues:XYZ]. The build_ios_app action generates the following Lane Variables:

SharedValue Description
SharedValues::IPA_OUTPUT_PATH The path to the newly generated ipa file
SharedValues::DSYM_OUTPUT_PATH The path to the dSYM files
SharedValues::XCODEBUILD_ARCHIVE The path to the xcodebuild archive

To get more information check the Lanes documentation.


To show the documentation in your terminal, run

fastlane action build_ios_app



fastlane run build_ios_app


fastlane run build_ios_app parameter1:"value1" parameter2:"value2"



Source code


Back to actions