
React Native vs native (Swift/Kotlin) in 2026: when to choose which
Performance benchmarks, developer experience, ecosystem and five use-case recommendations. React Native or native: decide on technical grounds, not habit.
A step-by-step guide to iOS App Store and Google Play Store deployment: developer accounts, certificates, the review process and Fastlane automation.

Release pipeline
Xcode Archive or Gradle bundleRelease. Fastlane Match handles certificate and keystore rotation.
TestFlight on iOS, Closed Testing on Android. Pre-launch reports via Firebase Test Lab, review crashes and ANRs.
App Store turns around in 24-48h, Google Play in 12-24h. Privacy and Data Safety forms must match the SDKs.
Production rollout 1% → 5% → 20% → 50% → 100% with Crashlytics watching for spikes that trigger a halt.
A mobile app is built — but deployment often feels harder than it actually is. A 2-3 week slip in App Store / Play Store review is common, but avoidable with the right preparation. This guide walks through the full flow from a new developer's perspective: account setup, certificate management, build configuration, metadata upload, the review process, and Fastlane-based automation.
This guide reflects the state of things in Q1 2026. Apple and Google policies change quickly — it's worth checking the official documentation too, especially around privacy declarations and target API level.
Before you start, a few things need to be in place. These are often left to the last minute, and that causes a 1-2 week slip.
Tip: Preparing icons and screenshots is often 1-2 days of design work. Schedule time for it outside deployment week.
Apple Developer Portal → Certificates, Identifiers & Profiles → Identifiers → new App ID. Bundle ID convention: com.companyname.appname. Reverse-DNS notation, lowercase, hyphens allowed.
Bundle ID examples:
✓ com.corevanix.partneriapp
✓ hu.cegnev.flotta-mobile
✗ com.corevanix.PartneriApp (uppercase not allowed)
✗ corevanix.app (not reverse-DNS)
Never change the Bundle ID after release — it counts as a new app, and all user data is lost.
Every capability you use has to be explicitly enabled on the App ID:
Every new capability requires its own provisioning profile — plan for this ahead of time.
Two certificates are needed:
Provisioning Profile for the Distribution certificate. Xcode can handle all of this automatically (Automatically manage signing), but in production it's better to manage it manually — automatic signing often breaks in CI/CD environments.
# Export a local cert from iCloud Keychain
security find-identity -p codesigning -v
# Lists the stored certificates
Xcode → Product → Scheme → Edit Scheme → Run → Build Configuration: Release. Plus:
Goal: the archive should appear clean in Window → Organizer, with no warnings.
App Store Connect → My Apps → new app:
This is the time-consuming part. Every field is required:
The App Privacy declaration has been mandatory since 2020. The "Data Used to Track You," "Data Linked to You," and "Data Not Linked to You" categories need to be marked precisely.
Xcode → Product → Archive → Distribute App → App Store Connect → Upload.
Typical build processing time: 15-60 minutes. Extreme cases of 4-6 hours do happen, especially on release days.
# With Fastlane:
fastlane ios beta
After the build is processed, warnings may appear (Missing Marketing Icon, ITSAppUsesNonExemptEncryption, etc.). You'll see them under App Store Connect → TestFlight.
App Store Connect → Version → select the build → Submit for Review.
Pre-submission checklist:
Typical review time: 24-48 hours (before 2025 it was 3-7 days — it has sped up a lot). Possible outcomes:
The first 24-48 hours are critical:
| Rejection reason | Fix |
|---|---|
| Crash on launch | Test on every iOS version (min target → latest) |
| Privacy policy URL broken | Check it manually, in Hungarian and English |
| Sign-in required without explanation | Provide a guest mode or explain the value |
| In-app purchase not relevant, but uses a Stripe flow | Apple only allows IAP for digital services |
| Medical/financial claim without a disclaimer | Add an appropriate disclaimer |
| Insufficient unique content (clone) | The app needs to provide real value |
| Inappropriate content | Content policy review |
| Missing required functionality | The app can't be a placeholder |
Note: If you get a rejection, don't restart the flow from step 0. You can talk to the reviewer through the Resolution Center — the issue is often resolved after 1-2 replies.
Convention: com.companyname.appname. The application ID is set in build.gradle — never change it after launch.
// app/build.gradle.kts
android {
namespace = "com.corevanix.partneriapp"
defaultConfig {
applicationId = "com.corevanix.partneriapp"
versionCode = 1
versionName = "1.0.0"
minSdk = 26
targetSdk = 35 // 2026: Android 15
}
}
keytool -genkey -v -keystore release.keystore \
-alias upload -keyalg RSA -keysize 2048 -validity 10000 \
-storepass <password> -keypass <password> \
-dname "CN=Corevanix Kft., O=Corevanix, C=HU"
LOSE THE KEYSTORE FILE OR PASSWORD = LOSE THE APP (you cannot publish updates with a new keystore, only a new app). Store it somewhere secure (1Password, Bitwarden, HashiCorp Vault).
Since the 2021 change, Google Play generates and holds its own signing key. Your AAB, signed with your "upload key," gets re-signed by Google with its own production key.
Benefit: if you lose your upload keystore, Google can generate a new upload key — the app is NOT lost.
Play Console → App Signing → Use Google Play App Signing
→ Upload your upload key certificate (or generate new)
Play Console → All apps → Create app:
cd android
./gradlew bundleRelease
The AAB lands in app/build/outputs/bundle/release/app-release.aab. It's the modern alternative to APK (smaller, Google dynamically splits it into platform-specific APKs).
# With Fastlane in RN:
fastlane android beta
Always put the release on the Internal Testing track first. Resubmissions are unlimited and free, and it's live at the beta level within 1-2 hours.
Play Console → Internal testing → Create release → Upload AAB.
Google automatically runs the build through Firebase Test Lab (roughly 30 virtual devices), flagging crashes, ANRs, and security issues.
The pre-launch report takes 2-6 hours. Results:
After Internal, test with 50-1,000 beta users on Closed Testing. Move to the Production track once feedback is positive.
Closed Testing's benefit: real user feedback before the production submission. A 2-4 week cycle is typically worth running.
Phased rollout: 1% → 5% → 20% → 50% → 100%. Monitor crash analytics at every stage. If there's a crash spike, halt the rollout.
Day 1: 1% rollout
Day 2: 5% rollout
Day 4: 20% rollout
Day 7: 50% rollout
Day 14: 100% rollout
Google Play review: 1-3 days on first submission, 12-24 hours afterward. Common issues:
| Issue | Fix |
|---|---|
| Permissions too broad | Request only the permissions you actually use |
| Privacy policy / Data Safety form inaccurate | Update the Data Safety section |
| Incomplete data declaration | Declare every type of data collected |
| Target API level too old (2026: min 35) | Update minSdk and targetSdk |
| App content policy violation | Review the Google Play policies |
| Spam / clone app | The app needs to provide unique value |
| Restricted content (e.g. pharmaceuticals) | Special approval / disclaimer |
Tip: The Data Safety form has been stricter since 2024. Every third-party SDK (Firebase, Mixpanel, OneSignal) has to have its data collection declared. Don't skip Sentry either — it also collects data.
On a single project, you're running builds for two stores at once. To keep versions in sync:
// package.json (RN example)
{
"version": "1.4.2"
}
// Build scripts use this for both platforms
// iOS: CFBundleShortVersionString
// Android: versionName
Keep the build number in sync as well — it simplifies debugging when a bug report comes in.
If the two platforms have different features (e.g. Live Activity on iOS only), two things matter:
Keep a Notion or Linear doc with all the store metadata: description, screenshot links, version history. Onboarding a new team member then takes 30 minutes.
A manual deployment takes 2-3 hours per release. With Fastlane, it takes 5-10 minutes.
# On iOS
cd ios
fastlane init
# On Android
cd android
fastlane init
# fastlane/Fastfile
default_platform(:ios)
platform :ios do
desc "Push a new beta build to TestFlight"
lane :beta do
increment_build_number(xcodeproj: "MyApp.xcodeproj")
build_app(
scheme: "MyApp",
export_method: "app-store",
output_directory: "./build",
)
upload_to_testflight(
skip_waiting_for_build_processing: true,
changelog: changelog_from_commits,
)
slack(
message: "iOS beta build #{lane_context[SharedValues::BUILD_NUMBER]} uploaded",
)
end
desc "Submit for App Store review"
lane :release do
capture_screenshots
build_app(scheme: "MyApp")
upload_to_app_store(
submit_for_review: true,
automatic_release: false,
)
end
end
platform :android do
desc "Push a new build to Internal Testing"
lane :beta do
gradle(task: "bundleRelease")
upload_to_play_store(
track: "internal",
aab: "app/build/outputs/bundle/release/app-release.aab",
)
end
desc "Production release"
lane :release do
gradle(task: "bundleRelease")
upload_to_play_store(
track: "production",
rollout: "0.05", # 5% phased rollout
)
end
end
# .github/workflows/mobile-beta.yml
name: Mobile Beta
on:
push:
branches: [main]
jobs:
ios-beta:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: 3.2
bundler-cache: true
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: bundle exec fastlane ios beta
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APP_STORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
android-beta:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- uses: ruby/setup-ruby@v1
with:
ruby-version: 3.2
bundler-cache: true
- run: npm ci
- run: bundle exec fastlane android beta
env:
PLAY_STORE_JSON_KEY: ${{ secrets.PLAY_STORE_JSON_KEY }}
Certificate management is much easier with Fastlane Match:
# Matchfile
git_url("git@github.com:corevanix/mobile-certificates.git")
storage_mode("git")
type("appstore")
app_identifier(["com.corevanix.partneriapp"])
username("info@corevanix.com")
The match appstore command downloads and installs the certificates. Automatic in CI, about 30 seconds locally.
The two beta channels suit different use cases:
| Aspect | TestFlight (iOS) | Closed Testing (Android) |
|---|---|---|
| Max users | 10,000 | Unlimited (per group) |
| Beta period | 90 days | Unlimited |
| Crash reports | Yes | Yes (Crashlytics) |
| Beta feedback | In-app + email | Email + Play Console |
| Review needed | Internal: no; External: yes (24h) | No |
| Distribution | Email invite or public link | Email invite or public link |
| Setup time | 1 day | 2-4 hours |
A "real" beta runs 2-4 weeks. 50-100 users are enough to catch the major bugs, without generating so much feedback that it becomes unmanageable.
Day 1-2: 5% rollout — watch the crash rate
Day 3-5: 20% rollout — continue if crashes stay below 0.5%
Day 6-10: 50% rollout — keep watching
Day 11-14: 100% rollout
A halt-and-hot-fix cycle takes 1-2 days. It's better to halt than to keep rolling out to 100%.
Rollback is hard on iOS: an app can't be rolled back to an "older" version. The workaround is submitting a new release with the old build (as an incremental version).
On Android, the Play Console "Halt rollout" button helps, but there's no auto-rollback for users who already installed the new version.
The defensive strategy is feature flags. New features ship off by default and can be flipped server-side.
Debug builds are slower, larger, and often contain dev-only credentials. Always use the Release configuration.
This is the #1 cause of auto-rejection. The privacy policy URL needs to be live and available in Hungarian and English (for multi-locale apps).
"Best," "top," "guaranteed" — these can violate marketing policies. Only use them if they're actually verifiable.
The reviewer looks at the screenshots, and placeholder text ("Lorem ipsum") in them triggers an automatic rejection.
If you use tracking data (Firebase, Google Analytics, Facebook SDK), the App Tracking Transparency prompt is mandatory. Skipping it is one of the most common causes of privacy-violation auto-rejection.
Related articles from us: React Native vs. Native in 2026 — choosing a platform. Getting push notifications right — designing a push flow. Mobile app GDPR compliance — privacy fundamentals before deployment.
Typically 24-48 hours as of 2026, down from the 3-7 days it used to take before 2025.
1-3 days for a first submission, 12-24 hours for subsequent releases.
No. Changing either one after release counts as publishing a new app, and all existing user data is lost.
Mobile deployment in 2026 is faster than ever — but the setup remains steep. Plan for 2-4 weeks for your first store submission (certificates, metadata, screenshots, the first review).
Setting up an automated pipeline (Fastlane + GitHub Actions) takes 1-2 days of development, but after that every release takes 5-10 minutes. It's worth it.
After the first release, every subsequent one gets easier. By the third release it already feels routine, and by the tenth it's essentially automatic. The investment goes into the initial setup — after that, deployment friction largely disappears.
If you're planning a mobile app project, let's talk through your deployment and store strategy — taking ownership of the release process is part of our build package. On the first release, our partner developer personally checks every step to make sure the handover goes cleanly.
About the author
Corevanix Kft.
Technology partner
Budapest-based technology partner — SAP/ERP integration, web development, AI automation and mobile app development. We work inside the client’s own environment, and the delivered code belongs entirely to the client.

Performance benchmarks, developer experience, ecosystem and five use-case recommendations. React Native or native: decide on technical grounds, not habit.

Push notifications are a top-three retention tool, or a top-three reason to uninstall. Ten common mistakes and the correct implementation, with code.

GDPR basics on mobile, consent management, IDFA / GAID handling, analytics tools and an audit checklist: a concise summary of the 2026 essentials.