iOS App Build — Xcode · Signing · TestFlight
iOS App Build — Xcode · Signing · TestFlight
iOS app builds go through similar steps to Android (compile → bundle resources → sign → package), but the tools, distribution channels, and policies look quite different. The biggest difference is that macOS and the Apple Developer Program are effectively required. This post covers Xcode and xcodebuild, certificates, provisioning profiles, signing modes, TestFlight, App Store review, and how Tauri / Flutter / RN differ in iOS builds.
1. The surface of iOS builds
| Event | Time |
|---|---|
| Xcode 1.0 (Mac OS X) | 2003 |
| iPhone SDK released | 2008 |
| App Store launched | 2008 |
| TestFlight acquired (Apple) | 2014 |
| App Tracking Transparency (ATT) | 2021 (iOS 14.5) |
| Notarization · Privacy Manifest tightened | 2024 ~ |
Tools:
- Xcode — integrated IDE + build system + simulator.
- xcodebuild — command-line build tool. Installed with Xcode.
- Xcode CLI Tools — only the Xcode command-line tools (
xcode-select --install). The mac-standard entry to gcc / clang / git. - Apple Developer Program — 99 USD a year. Required to distribute to real devices and to publish on the App Store.
# Mac only (iOS builds require macOS)
xcode-select --install
xcodebuild -version
2. Build flow
.swift / .m → swiftc / clang → .o
.storyboard · .xcassets → compile → asset catalog
Info.plist · entitlements → merge
link → executable binary
↓
.app bundle (a directory-shaped package)
↓
sign (codesign)
↓
.ipa (zipped .app)
Similar to how Android's APK packs DEX, resources, and a manifest in a ZIP, iOS's .ipa is essentially a zipped Payload/MyApp.app directory.
Bundle Identifier — the global ID of the app. Usually a reverse-DNS shape (com.example.myapp). Once registered in the App Store, it's almost impossible to change. Maps to App ID in the Apple Developer console.
Info.plist · entitlements:
| File | Meaning |
|---|---|
Info.plist |
Bundle metadata (name, version, icon, required device features, permission descriptions) |
*.entitlements |
Security features the app uses (iCloud, Push, Sign in with Apple) |
After ATT (App Tracking Transparency, iOS 14.5+), using IDFA requires both the NSUserTrackingUsageDescription key and a runtime consent dialog.
3. Signing
The iOS signing model has more entangled objects than Android.
Certificate — developer certificate issued by Apple:
- Development Certificate — for installing directly on devices.
- Distribution Certificate — for TestFlight, App Store, Ad Hoc.
Generate the key pair in macOS Keychain and upload the CSR to the Developer console — that's the standard flow.
App ID — app identifier registered in the Apple console. Maps to Bundle Identifier. Either com.example.myapp or a wildcard com.example.*.
Device — for Ad Hoc and Development distribution, only registered device UDIDs can install. There is a per-account device cap (about 100 per year).
Provisioning Profile — a file (.mobileprovision) bundling the three above (certificate, App ID, devices). Packaged inside the built .app and verified by the device at install time:
| Profile type | Purpose |
|---|---|
| Development | Direct install on registered devices |
| Ad Hoc | Distribution to registered devices |
| App Store | App Store · TestFlight distribution |
| Enterprise | Internal enterprise distribution (separate from a regular developer account) |
Automatic vs Manual Signing — turning on "Automatically manage signing" in Xcode automates certificate and profile issuance and renewal. CI environments often use manual mode. The manual flow typically uses a tool like fastlane match to sync certificates and profiles to a (encrypted) git repo.
4. Distribution channels
TestFlight — Apple's beta distribution system. Up to 100 internal users and 10000 external users can be invited. External beta has a brief review on the first build.
App Store Connect — the App Store registration and review console. Metadata, screenshots, review notes, pricing, release schedule. The build itself is uploaded via Xcode or Transporter.
Ad Hoc — direct distribution to up to 100 registered devices, bypassing the App Store. For internal demos and user trials.
Enterprise — separate from the regular Developer Program, the Enterprise Program (299 USD a year, requires application review). Allows distributing apps to in-house employees outside the App Store. Discovered external use leads to revocation.
5. App Store review
The big themes of the review guidelines:
- Functional safety — no crashes or critical bugs, promised features actually work.
- Metadata accuracy — screenshots and description match the actual app.
- Privacy · permissions — clear reasons in permission prompts. ATT and PII protection.
- Payments — digital content is in principle IAP (In-App Purchase, 30% / 15% fee). Physical goods and some external-payment scenarios are exceptions.
- Category-specific policies — kids, health, finance, and gambling have extra requirements.
If review is rejected, the reason is communicated and you fix-and-resubmit. Average review time is often reported within 24 ~ 48 hours, but it varies by season.
6. iOS builds in cross-platform tools
Tauri Mobile, Flutter, and React Native all end up using the same Xcode + xcodebuild flow:
- Compile or bundle their own code (Rust, Dart, JS).
- Auto-generate and manage the Xcode project (the
ios/directory). - Produce
.ipaviaxcodebuild archiveandxcodebuild -exportArchive. - Manage certificates and profiles via Xcode or fastlane.
| Tool | Note |
|---|---|
| Tauri 2 (mobile) | Rust + WebView. Auto-generated Xcode project. Relatively new. |
| Flutter | Dart + Skia / Impeller. Stable iOS build. fastlane integration is common. |
| React Native | JS + native bridge. CocoaPods dependency. EAS Build (Expo) is the standard place. |
Across all tools, macOS being effectively required for iOS builds is a constant. Trying to build iOS on Linux / Windows is very limited (workarounds like Cirrus CI, MacStadium, GitHub Actions macOS runners).
7. Common patterns
CLI build:
# Mac
xcodebuild -workspace MyApp.xcworkspace \
-scheme MyApp \
-configuration Release \
-archivePath build/MyApp.xcarchive archive
xcodebuild -exportArchive \
-archivePath build/MyApp.xcarchive \
-exportOptionsPlist ExportOptions.plist \
-exportPath build/
# Windows: cannot build directly. Use a macOS runner (GitHub Actions · self-hosted).
TestFlight upload:
# Mac (Transporter CLI)
xcrun altool --upload-app -f build/MyApp.ipa \
-u "you@apple.id" -p "@keychain:AC_PASSWORD"
fastlane (the standard tool for iOS · Android deployment automation. A Ruby gem):
lane :beta do
match(type: "appstore")
build_app(workspace: "MyApp.xcworkspace", scheme: "MyApp")
upload_to_testflight
end
match keeps certificates and profiles encrypted in a git repository so the team and CI can share them.
CI matrix:
- GitHub Actions —
macos-latestrunner. Per-hour pricing. - CircleCI · Bitrise · Codemagic — iOS-friendly hosts.
- Self-hosted Mac mini · MacStadium — stable cost control.
8. Common pitfalls
Certificate expiry — Distribution certificates are usually valid for 1 year. After expiry, no new .ipa can be built. Reissue and renew all profiles.
Missing provisioning profile — the entitlements of the built .app must match the profile. Mismatch causes rejection at install on the device.
Bundle ID change is impossible — virtually no way to change after release. Register as a new app instead.
iOS version compatibility — too low an IPHONEOS_DEPLOYMENT_TARGET requires runtime branching for some APIs. Too high narrows user reach.
Missing ATT — using an SDK with IDFA but skipping the usage description → rejection. Check when using AdMob or ad SDKs.
Privacy Manifest (2024 ~) — some SDKs require a Privacy Manifest. Missing it causes rejection.
Encryption export — Info.plist ITSAppUsesNonExemptEncryption. Using only HTTPS usually qualifies as exempt.
CocoaPods · SwiftPM conflict — when both dependency managers are used in one project, conflicts arise. Gradual migration to SPM is the trend.
Closing thoughts
iOS builds carry more operational burden than Android due to macOS + the Apple Developer Program + the multi-layer certificate / profile / device model + App Store review + ATT / Privacy Manifest policies. fastlane match is the standard for team and CI automation, and yearly certificate expiry and policy updates are recurring spots. Step in when the business value is clear.
Next
- (mobile end)
Apple Developer Documentation · App Store Review Guidelines · Xcode Help · TestFlight · fastlane official · Transporter · Tauri Mobile · Flutter iOS deployment for reference.