edit

Xcode Archive: export options

If you create a new iOS app on bitrise.io the generated default workflow wil include our Xcode Archive step. This step can manage to archive and export your iOS app.

A bit of history and technical info

If the step is used with Xcode 6 it'll generate the following (legacy) command to export the ipa of your app (you can see it in the step's log):

xcodebuild -exportArchive \
    -exportFormat ipa \
    -archivePath "/var/folders/lb/8n5bn9k975qgw662jpqdy7mm0000gn/T/bitrise-xcarchive.YnAMfpzJ/ios-simple-objc.xcarchive" \
    -exportPath "/Users/vagrant/deploy/ios-simple-objc.ipa" \
    -exportProvisioningProfile "Xyz"

Back in the days of Xcode 6 this was everything you had to do; just specify the format to be ipa and set the required paths and the Provisioning Profile to be used for code signing the ipa.

Xcode 7 instroduced a lot of additional archive feature and the support for defining more complex archive parameters. This meant that although Xcode 7 still supports the old parameters, it's now declared as deprecated, and you'd get the following warning if you'd use the old parameters instead of the new -exportOptionsPlist parameter:

xcodebuild: WARNING: -exportArchive without -exportOptionsPlist is deprecated

The export command's new version expects a Plist file (-exportOptionsPlist), which should include all the archive parameters (including code signing type/method, and other parameters like enable/disable Bitcode). The full command looks like this:

xcodebuild -exportArchive \
    -archivePath "/var/folders/lb/8n5bn9k975qgw662jpqdy7mm0000gn/T/bitrise-xcarchive.QbpHVvNx/ios-simple-objc.xcarchive" \
    -exportPath "/var/folders/lb/8n5bn9k975qgw662jpqdy7mm0000gn/T/bitrise-xcarchive.aCvNPRAi" \
    -exportOptionsPlist "/Users/vagrant/deploy/export_options.plist"

By default the Xcode Archive step generates the minimal sufficient Plist file, with only the export method defined in it (unless you specify the export_options_path input, we'll get back to this a bit later):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>method</key>
    <string>development</string>
</dict>
</plist>

About the Xcode Archive step generated export options

The default generated export options Plist file only specifies the export method (app-store, ad-hoc, enterprise or development) based on the provisioning profile embedded in the .xcarchive (which is generated by the xcodebuild archive command, also performed by the Xcode Archive step, right before the xcodebuild -exportArchive command).

The embedded provisioning profile depends on your code sign settings in your project. You can force the desired code signing configuration with Xcode Archive step's force_code_sign_identity and force_provisioning_profile inputs. You can find more information about these options in the iOS Code Signing article.

Every other export option which can be defined in the Plist is optional.

Use your own export options

In case of the default export_options.plist does not fit your needs, you can specify your own export options too. To do this create a plist file (in your repository) with the options you want to use.

Available export options

You can get a list of all available options by calling xcodebuild -h - check the Available keys for -exportOptionsPlist: section of the printed help.

These are the options you can select in Xcode when you export the ipa manually.

The recommanded way is to put this generated plist file in your project's repository. Then you can set Xcode Archive step's export_options_path input to the path of your plist file (e.g. ./path/to/export-options.plist).

Disable bitcode in ipa

By default uploadBitcode export options is set to YES, unless you specifically disable it in the export options Plist. If it does not fit your requirements you have to use your own export options, instead of the archive steps generated one.

Your export options plist should look like:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>method</key>
    <string>app-store</string>
    <key>uploadBitcode</key>
    <false/>
</dict>
</plist>

Code Signing note

Of course, if you set the method to app-store then you have to upload / use an App Store code signing Identity & Provisioning Profile (it have to be available in the system).

ERROR ITMS-90635: Invalid Mach-O Format

Transporter Error Output: ERROR ITMS-90635: Invalid Mach-O Format.
...
Verify that all of the targets for a platform have a consistent value for the ENABLE_BITCODE build setting.
...

This error occurs if you have different ENABLE_BITCODE settings in your (sub)projects, including the projects generated by CocoaPods for example.

If you use CocoaPods you can override the ENABLE_BITCODE in the pod projects by adding the following section to your Podfile:

For CocoaPods 1.0+:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['ENABLE_BITCODE'] = 'NO'
    end
  end
end

For CocoaPods 0.39 and below:

post_install do |installer|
  installer.project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['ENABLE_BITCODE'] = 'NO'
    end
  end
end