Quick reference for iOS and Android release: signing artifacts, keystores, fastlane and EAS commands, build and upload commands, store listing checklist, rejection reasons, and an Apple vs Google comparison.
Code SigningProvisioningStore ListingsCI/CD
iOS Signing Artifacts
What each piece does
| Artifact | Purpose |
| Development cert | Sign builds for debugging on device |
| Distribution cert | Sign TestFlight / App Store builds |
| App ID | Bundle id + enabled capabilities |
| Entitlements | Capabilities baked into binary (.entitlements) |
| Provisioning profile | App ID + certs + entitlements + device UDIDs |
Profile types
| Type | Devices | Use |
| Development | UDIDs | Debug |
| Ad Hoc | UDIDs (max 100) | Off-store tests |
| App Store | None | TestFlight / Store |
Android Signing
Keys
| Key | Held by | Role |
| Upload key | You | Signs the .aab you upload (resettable) |
| App signing key | Google | Re-signs artifact for users (permanent) |
Generate keystore
keytool -genkeypair -v -keystore upload.jks \
-alias upload -keyalg RSA -keysize 2048 -validity 10000
signingConfigs (build.gradle.kts)
signingConfigs {
create("release") {
storeFile = file(System.getenv("KEYSTORE_PATH"))
storePassword = System.getenv("KEYSTORE_PASSWORD")
keyAlias = "upload"
keyPassword = System.getenv("KEY_PASSWORD")
}
}
fastlane Commands
Core actions
| Action | Does |
| match | Sync iOS certs/profiles from shared repo |
| gym | Build/export the .ipa |
| deliver | Upload iOS binary + metadata |
| supply | Upload Android .aab + listing |
fastlane match appstore --readonly
fastlane gym --scheme App
fastlane pilot upload # TestFlight
fastlane deliver --submit_for_review
fastlane supply --track internal --aab app.aab
EAS Commands
eas login
eas build:configure
eas build --platform all --profile production
eas submit --platform ios --latest
eas submit --platform android --latest
eas credentials # manage signing
eas build --platform ios --profile preview # ad hoc / internal
Build & Upload
iOS (xcodebuild)
# Archive
xcodebuild -scheme App -configuration Release \
-archivePath build/App.xcarchive archive
# Export .ipa
xcodebuild -exportArchive \
-archivePath build/App.xcarchive \
-exportPath build -exportOptionsPlist ExportOptions.plist
# Upload with App Store Connect API key
xcrun altool --upload-app -f build/App.ipa \
--apiKey $KEY_ID --apiIssuer $ISSUER_ID
Android (gradlew)
./gradlew bundleRelease # -> app-release.aab (upload to Play)
./gradlew assembleRelease # -> app-release.apk (sideload/QA)
./gradlew clean bundleRelease --stacktrace
Store Listing Checklist
[ ] App name / title + subtitle / short description
[ ] Full description
[ ] App icon 1024x1024
[ ] Screenshots (iPhone 6.9"/6.5", iPad 13"; Play phone/7"/10")
[ ] Feature graphic 1024x500 (Play)
[ ] Keywords field 100 chars (Apple) / ASO in description (Play)
[ ] Privacy policy URL
[ ] Privacy Nutrition Labels (Apple) / Data safety form (Play)
[ ] Age / content rating (Apple band, Play IARC)
[ ] Category + support/marketing URLs
[ ] Demo account for reviewer (if login required)
[ ] Build number > previous upload
Common Rejection Reasons
| Reason | Fix |
| Crashes / bugs | Test on real device + reviewer region |
| Privacy | Add policy, match labels to behavior |
| IAP bypass | Use StoreKit / Play Billing for digital goods |
| Guideline 4.3 (spam) | Add unique value; avoid reskins/templates |
| Incomplete info | Provide demo login, working links, notes |
| Broken metadata | Screenshots must reflect real UI |
Apple vs Google
| Aspect | Apple | Google |
| Fee | $99/yr | $25 once |
| Review | < 24h, human | Hours-days, automated |
| Artifact | .ipa | .aab (required) |
| Signing | Certs + profiles | Keystore + Play App Signing |
| Test | TestFlight | Internal/closed/open |
| Rollout | Phased (7d) | Staged (%) |
| Cut | 15% / 30% | 15% / 30% |