
iOS / visionOS / macOS → TestFlight
iOS / visionOS / macOS → TestFlight
Ship native iOS, visionOS, and macOS apps to TestFlight from the command line — xcodebuild archive, xcodebuild -exportArchive, xcrun altool. No Xcode Organizer clicks, no Transporter app, no manual provisioning dance. Multi-platform Swift apps that ship a single binary for both iOS and visionOS are covered by the same one-archive flow.
This is the workflow I use in production for Apple-native Swift/SwiftUI projects. Every gotcha documented here is one I hit on a real shipping build.
What it does
- Single-command archive + export + upload — one
xcodebuild archiveplus onexcodebuild -exportArchivewithdestination: uploadand your.ipa(iOS/visionOS) or.pkg(macOS) lands in App Store Connect. - iOS, visionOS, or both from one archive — the
xrosdestination produces a multi-platform binary that App Store Connect makes available for both platform categories. - macOS support too — same pipeline,
generic/platform=macOS, automatic.pkgpackaging viamethod: app-store-connect, with the Mac App Distribution + Mac Installer Distribution cert pair pulled by-allowProvisioningUpdates. - ASC API key auth —
.p8+ Key ID + Issuer ID, discovered byaltoolautomatically. No passwords, no Transporter, no app-specific passwords. -allowProvisioningUpdateseverywhere — Xcode pulls and refreshes profiles without GUI prompts, even after cert rotation.- 10 production gotchas documented — the silent "configuration errors:" export failure,
/Users/SharedBUILD_DIRpermission traps, thealtooldeprecation red herring, stale profile caches after cert rotation, the two-cert macOS requirement, the.pkg-not-.appASC rule, hardened-runtime + sandbox entitlements, the always-bump-build-number rule, and more.
Who it's for
- iOS / visionOS / macOS devs who want a deterministic CLI pipeline they can drop into CI or a shell alias
- Multi-platform Swift app shippers who don't want to manage two archives for two platforms
- Mac App Store devs tired of the "no signing certificate found" loop between Mac App Distribution and Mac Installer Distribution
- Anyone who has ever stared at "Cannot export project ... due to configuration errors:" with no error after the colon and asked "what configuration errors?"
What you get
- A complete
SKILL.mdcovering the full pipeline end-to-end for all three platforms - A drop-in
testflight.shshell script you can run asPLATFORM=iOS bash testflight.sh 42 1.3.0(orxros, ormacOS) - A working
ExportOptions.plisttemplate that works unchanged for all three platforms - Platform-destination cheat sheet (iOS / visionOS / macOS / multi-platform)
- A debugging section keyed to the actual error strings
xcodebuildandaltoolproduce
One-time setup after download
You need an Apple Developer Program membership and an App Store Connect API key. Roughly 10 minutes of clicking the first time, zero clicks every time after.
1. Apple Developer Program
Enroll at developer.apple.com ($99/year). Required for the Apple Distribution certificates (iOS/visionOS use Apple Distribution; macOS uses Mac App Distribution + Mac Installer Distribution).
2. App Store Connect API key
- Go to App Store Connect → Integrations → Keys → Generate API Key
- Role: App Manager (or higher)
- Note the Key ID and Issuer ID
- Download the
.p8file — you cannot re-download it after leaving the page - Save it to
$HOME/.private_keys/AuthKey_<KEY_ID>.p8—altooldiscovers it there automatically
3. Shell environment
Add to $HOME/.zprofile:
export ASC_KEY_ID="ABC123DEFG"
export ASC_ISSUER_ID="69a6de7e-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export ASC_KEY_PATH="$HOME/.private_keys/AuthKey_${ASC_KEY_ID}.p8"
export DEVELOPMENT_TEAM="YOUR10CHARTEAMID"
4. App Store Connect record
Create the app record once in the portal (App Store Connect → My Apps → +). The API returns 403 on create — portal-only. The bundle ID must match your Xcode target's bundle identifier exactly. For Mac apps, pick macOS as the platform when creating; for multi-platform iOS+visionOS, pick iOS first then enable visionOS in the app's Pricing & Availability after the first upload lands.
5. Export compliance plist key
Add to Info.plist before archiving:
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
Forgetting this blocks the upload at validation time.
Platform coverage
| Platform | Archive destination | Upload format | Extra signing |
|---|---|---|---|
| iOS | -destination 'generic/platform=iOS' |
.ipa via direct upload or altool -t ios |
Apple Distribution |
| visionOS | -destination 'generic/platform=xros' |
.ipa (xros slice) |
Apple Distribution |
| Multi-platform (iOS + visionOS) | -destination 'generic/platform=xros' |
One .ipa, both platforms enabled in ASC |
Apple Distribution |
| macOS | -destination 'generic/platform=macOS' |
.pkg via direct upload or altool -t macos |
Mac App Distribution and Mac Installer Distribution |
Timeline expectations
| Phase | Time |
|---|---|
| First-time setup (cert(s), ASC key, app record) | ~10 min (iOS/visionOS); ~15 min (macOS — two certs) |
| Archive (clean build, mid-size app) | 2–8 min |
Export + upload (direct destination: upload) |
1–5 min |
| ASC validation → VALID status | Instant after upload |
| Build visible in TestFlight | 5–30 min (Apple processing) |
| External testers (new group) | Additional review required |
Requires
- A Mac with Xcode 15 or newer (Xcode 16+ recommended for visionOS)
- Active Apple Developer Program membership
- App Store Connect API key with App Manager role
- An app record in App Store Connect (portal-only to create)
- For Mac apps: Mac App Distribution + Mac Installer Distribution certificates (Xcode can request both for you with
-allowProvisioningUpdates)
This is a workflow skill — it does not include Xcode, the iOS/visionOS/macOS SDKs, or any Apple developer credentials. Those remain on your machine.
External APIs
https://api.appstoreconnect.apple.com · https://appstoreconnect.apple.com · https://developer.apple.com



