exportOptions.plist is the configuration file behind xcodebuild -exportArchive. The archive step produces one signed .xcarchive; the export step re-signs and repackages it for a specific destination (App Store, testers, enterprise), and every decision it makes comes from this plist. Nearly every iOS CI pipeline has one checked into the repo.
The method key
method picks the distribution type, which in turn decides which kind of provisioning profile the export needs. Recent Xcode releases renamed the methods; both spellings are accepted, but new projects should use the new names.
| Method (current) | Legacy name | Used for | Profile type |
|---|---|---|---|
| app-store-connect | app-store | App Store and TestFlight | App Store profile |
| release-testing | ad-hoc | Registered test devices | Ad Hoc profile |
| debugging | development | Development installs | Development profile |
| enterprise | enterprise | In-house distribution | Enterprise profile |
| developer-id / mac-application | same | macOS outside the App Store | Developer ID signing |
A minimal automatic-signing example
<?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>app-store-connect</string> <key>teamID</key> <string>ABCDE12345</string> <key>signingStyle</key> <string>automatic</string> </dict> </plist>
Manual signing on CI
CI machines usually sign manually with a known certificate and profile, because automatic signing wants portal access mid-build. Manual style adds two keys: the certificate name and a map from bundle ID to profile.
<key>signingStyle</key> <string>manual</string> <key>signingCertificate</key> <string>Apple Distribution</string> <key>provisioningProfiles</key> <dict> <key>com.example.myapp</key> <string>MyApp App Store</string> </dict>
The provisioningProfiles value is the profile's name or its UUID. Name matching is the common choice, and it is also the common failure: rename the profile in the portal (or regenerate it under a new name) and the export breaks until the plist is updated.
Other keys worth knowing
uploadSymbols(bool): include dSYMs so crash reports symbolicate. Defaults to true for App Store exports.manageAppVersionAndBuildNumber(bool): lets the export bump the build number to the next valid one on App Store Connect.destination(exportorupload):uploadsends the build straight to App Store Connect instead of writing an .ipa to disk.thinning: device-variant thinning for ad hoc exports, usually left at<none>.