Deploying to the App Store for the first time feels like navigating a bureaucracy with no map. Certificates expire silently, provisioning profiles mismatch at archive time, and App Store Connect throws validation errors that point nowhere useful. I've shipped over a dozen React Native apps to production on iOS and the process is always the same set of traps. This guide walks through every step — from a fresh Apple Developer account to your app going live — with the exact sequence that avoids those traps.
Step 1 — Apple Developer Program enrollment
Go to developer.apple.com and enrol in the Apple Developer Program ($99/year). Individual accounts are tied to your personal Apple ID — use a dedicated Apple ID for company projects, not your personal one. Organisation accounts require a D-U-N-S number (free, takes 1–5 business days to process via Dun & Bradstreet). Once enrolled, allow 24–48 hours for full activation before certificates become available. Everything else in this guide depends on an active membership.
Step 2 — Create an App ID
In the Apple Developer portal, go to Identifiers → App IDs → register a new App ID. Choose Explicit (not wildcard) and set the Bundle ID to match exactly what you have in Xcode — com.yourcompany.yourapp. Enable the capabilities your app uses: Push Notifications, Sign In with Apple, Associated Domains, etc. You cannot add certain capabilities later without regenerating your provisioning profile, so check this list thoroughly before continuing.
Step 3 — Distribution certificate
Go to Certificates → create a new Apple Distribution certificate. You will need to generate a Certificate Signing Request (CSR) from Keychain Access on your Mac: open Keychain Access → Certificate Assistant → Request a Certificate from a Certificate Authority → save to disk. Upload that CSR to the developer portal, download the resulting .cer file, and double-click it to install into your Mac's keychain. This certificate proves you are an authorised Apple developer. Keep the private key backed up — if you lose it, you must revoke and recreate.
Step 4 — Provisioning profile
Go to Profiles → create a new App Store Distribution profile. Select the App ID you created, select your Distribution certificate, name it clearly (e.g. YourApp AppStore Distribution), and download it. Double-click the .mobileprovision file to install it. In Xcode, go to your target → Signing & Capabilities → uncheck Automatically manage signing → under Release, manually select this provisioning profile and the Distribution certificate. Mismatches between the certificate in the profile and the one installed in your keychain are the most common archive failure.
Step 5 — Xcode build settings before archiving
# Make sure your Podfile targets release optimisations
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
if config.name == 'Release'
config.build_settings['SWIFT_OPTIMIZATION_LEVEL'] = '-Owholemodule'
config.build_settings['ENABLE_BITCODE'] = 'NO' # Bitcode deprecated in Xcode 14+
end
end
end
endIn Xcode, set the active scheme to your app target (not a test target) and the destination to Any iOS Device (arm64) — not a simulator. Open Product → Scheme → Edit Scheme → confirm the Run configuration is set to Release, not Debug. React Native's release build minifies JS and removes the Metro bundler dependency — never ship a Debug build to the App Store. Also bump your CFBundleShortVersionString (marketing version, e.g. 1.0.1) and CFBundleVersion (build number, must increment for every TestFlight or App Store upload) in Info.plist.
Step 6 — Archive and upload via Xcode Organizer
# From project root — generates the release bundle before archiving npx react-native bundle \ --platform ios \ --dev false \ --entry-file index.js \ --bundle-output ios/main.jsbundle \ --assets-dest ios # Then in Xcode: Product → Archive
After archiving, the Xcode Organizer opens automatically. Select your archive → Distribute App → App Store Connect → Upload. Xcode will validate the binary, check entitlements, and upload it to App Store Connect. This process takes 3–10 minutes depending on bundle size. If validation fails with a missing entitlement error, it means a capability is enabled in your code but not in your provisioning profile — go back to the developer portal, enable it on the App ID, and regenerate the profile.
Step 7 — TestFlight distribution
After upload, the build appears in App Store Connect → TestFlight within 5–15 minutes (sometimes longer on first upload). Internal testers (up to 100, no review required) can install immediately. External TestFlight groups require a Beta App Review — usually 1–2 days. Add testers by email or create a public link. TestFlight builds expire after 90 days, so keep pushing builds for longer beta periods. Always test the TestFlight build on a real device before submitting to App Store review — it uses the release bundle, not Metro, and catches issues that never appear in development.
Step 8 — App Store Connect metadata
In App Store Connect, create a new app version. You need: app name (30 chars max), subtitle (30 chars), description (4000 chars), keywords (100 chars total, comma-separated — these drive search ranking), support URL, marketing URL (optional), and privacy policy URL (mandatory for all apps since 2020). Screenshots are required for 6.7-inch iPhone (iPhone 15 Pro Max size), 12.9-inch iPad if you support iPad. Use Xcode Simulator to capture at the right dimensions. App Preview videos (30 seconds max) significantly improve conversion rates.
Step 9 — Submit for review
Select the build from TestFlight, fill in the export compliance (does your app use encryption beyond HTTPS? usually No for most apps), content rights declarations, and advertising identifier (IDFA) usage. Set the release type — automatic after approval, or manual (you release it yourself after approval). Average review time is 24–48 hours for a new app, 12–24 hours for updates. You can check App Review status on the App Store Connect app on iPhone for real-time notifications.
Common rejection reasons and fixes
Guideline 2.1 (App Completeness) — reviewers test on a real device and tap everything. Broken states, placeholder text, or non-functional buttons cause immediate rejection. Guideline 4.0 (Design) — your app must provide genuine value beyond a web view wrapper. Guideline 5.1.1 (Privacy) — every permission you request (camera, location, contacts) must be justified in the NSUsageDescription and actually used visibly. Requesting permissions not used in your app is an automatic rejection. Guideline 3.1.1 (Payments) — any digital goods or subscriptions must use Apple's In-App Purchase, not Stripe or PayPal directly.
Before every App Store submission: increment the build number (even for same-version re-submissions), test the exact TestFlight build on a physical device, verify all NSUsageDescription strings are present in Info.plist, confirm your privacy policy URL is live and accessible, and make sure the app works without an account login if reviewers cannot create one (provide demo credentials in the review notes).