2.8 KiB
2.8 KiB
Workflow: Ship iOS App
<required_reading> Read NOW:
- references/app-store.md
- references/ci-cd.md </required_reading>
- Version/build numbers updated
- No debug code or test data
- Privacy manifest complete (PrivacyInfo.xcprivacy)
- App icons all sizes (see references/app-icons.md)
- Screenshots prepared
- Release notes written
Step 2: Archive
xcodebuild archive \
-project AppName.xcodeproj \
-scheme AppName \
-archivePath ./build/AppName.xcarchive \
-destination 'generic/platform=iOS'
Step 3: Export for Distribution
For TestFlight/App Store:
xcodebuild -exportArchive \
-archivePath ./build/AppName.xcarchive \
-exportPath ./build/export \
-exportOptionsPlist ExportOptions.plist
ExportOptions.plist:
<?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>signingStyle</key>
<string>automatic</string>
</dict>
</plist>
Step 4: Upload to App Store Connect
xcrun altool --upload-app \
-f ./build/export/AppName.ipa \
-t ios \
--apiKey YOUR_KEY_ID \
--apiIssuer YOUR_ISSUER_ID
Or use xcrun notarytool with App Store Connect API.
Step 5: TestFlight
- Wait for processing in App Store Connect
- Add testers (internal or external)
- Gather feedback
- Iterate
Step 6: App Store Submission
In App Store Connect:
- Complete app metadata
- Add screenshots for all device sizes
- Set pricing
- Submit for review
Step 7: Post-Release
- Monitor crash reports
- Respond to reviews
- Plan next version
<privacy_manifest>
Required since iOS 17. Create PrivacyInfo.xcprivacy:
<?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>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
</array>
</dict>
</plist>
</privacy_manifest>
<common_rejections>
| Reason | Fix |
|---|---|
| Crash on launch | Test on real device, check entitlements |
| Missing privacy descriptions | Add all NS*UsageDescription keys |
| Broken links | Verify all URLs work |
| Incomplete metadata | Fill all required fields |
| Guideline 4.3 (spam) | Differentiate from existing apps |
| </common_rejections> |