Oct 5, 2017
Export .xcarchive to .ipa using xcodebuild for manually signed projects
The generic command
By now, if you are used to export a previously generated .xcarchive to .ipa using xcodebuild command line tool, you should be familiar with the following command :
xcodebuild -exportArchive -archivePath ${ARCHIVE_PATH} \
-exportPath ${EXPORT_PATH} \
-exportOptionsPlist ${EXPORT_OPTIONS_PLIST_PATH}.plist
The -exportOptionsPlist option is mandatory here, so you have to provide your own .plist file containing - you guessed it - the options for exporting your archive.
Before Xcode 9
The only required option was the export method : app-store, ad-hoc, enterprise or development.
Thus, your .plist file would look like the following :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>enterprise</string>
</dict>
</plist>
And that was it 🤓.
From now on
If you try to run the command with this .plist after you upgraded to Xcode 9, xcodebuild will sometimes answer with a Segmentation fault: 11.
Very nice, thank you ! 💩💀🖕< Goes on breaking things... >
Whoa, let’s keep our composure, please. What is going on here ?
Getting rid of the segmentation fault
After investigation, this came up while reading xcodebuild --help :
compileBitcode : Bool
For non-App Store exports, should Xcode re-compile the app from bitcode? Defaults to YES.
It seems that the flag compileBitcode being set to true by default, makes the whole thing fall apart. The solution is then to explicitly add the flag to the .plist and set it to false :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>compileBitcode</key>
<false/>
<key>method</key>
<string>enterprise</string>
</dict>
</plist>
Let’s run the command again…💥🔥
Okay, the segmentation fault is gone, but now xcodebuild says :
error: exportArchive: "YourAppName.app" requires a provisioning profile.
Apparently, xcodebuild needs more options in the .plist regarding provisioning.
Adding provisioning information
A new export option called provisioningProfiles is available :
provisioningProfiles : Dictionary
For manual signing only. Specify the provisioning profile to use for each executable in your app. Keys in this dictionary are the bundle identifiers of executables; values are the provisioning profile name or UUID to use.
Since the app is manually signed (as opposed to automatically managed by Xcode), you need to add this option to your .plist.
Resulting .plist
You should now be fine with the following :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>compileBitcode</key>
<false/>
<key>method</key>
<string>enterprise</string>
<key>provisioningProfiles</key>
<dict>
<key>your.bundle.identifier</key>
<string>Provisioning profile name</string>
</dict>
</dict>
</plist>