App Store Deployment: From Code to Production
App store deployment is the process of preparing, signing, and distributing mobile applications through Apple’s App Store and Google Play Store — involving code signing, provisioning profiles, versioning, release tracks, and compliance with store review guidelines.
What You’ll Learn
You’ll set up App Store Connect and Google Play Console, configure code signing and provisioning profiles, build app bundles and APKs, manage versioning, use release tracks (internal/alpha/beta/production), navigate app review guidelines, and implement in-app purchases.
Why App Store Deployment Matters
Building the app is only half the work. Getting it into users’ hands requires navigating complex deployment pipelines. Doda Browser and Durga Antivirus Pro go through this process for every update. Understanding deployment ensures your users always have the latest, most secure version of your app.
App Store Deployment Learning Path
flowchart LR
A[Mobile App Testing] --> B[Push Notifications]
B --> C[App Store Deployment]
C:::current
classDef current fill:#f90,color:#fff,stroke:#333,stroke-width:2px
App Store Connect Setup (iOS)
Step 1: Create an App Record
- Go to App Store Connect
- Navigate to Apps > + > New App
- Fill in:
- Platform: iOS (or visionOS/tvOS)
- Name: DodaBrowser
- Primary language: English
- Bundle ID: com.dodatech.browser (must match Xcode)
- SKU: DODABROWSER001
Step 2: Configure App Information
- Description: What your app does (up to 4000 characters)
- Keywords:
browser, privacy, secure - Support URL:
https://dodatech.com/support - Marketing URL:
https://dodatech.com - Privacy Policy URL:
https://dodatech.com/privacy(required)
Step 3: Upload Screenshots
- 6.5-inch iPhone: 4 screenshots (1242×2688 or 1290×2796)
- 5.5-inch iPhone: 4 screenshots (1242×2208)
- iPad Pro: 4 screenshots (2048×2732 or 2732×2048)
Code Signing (iOS)
Code signing proves your app comes from a legitimate developer and hasn’t been tampered with.
Xcode Automatic Signing
# In Xcode:
# 1. Select your target
# 2. Signing & Capabilities → "Automatically manage signing"
# 3. Select your team
# 4. Xcode creates provisioning profiles automaticallyManual Signing (CI/CD)
# Generate certificates and profiles manually:
# 1. Create Certificate Signing Request (CSR) via Keychain Access
# 2. Upload CSR to developer.apple.com
# 3. Download certificate (.cer) and install in Keychain
# 4. Create App ID and provisioning profile
# 5. Download profile (.mobileprovision)
# Fastlane match handles this elegantly:
match development --app_identifier "com.dodatech.browser"
match appstore --app_identifier "com.dodatech.browser"Provisioning Profiles
| Profile Type | Use | Devices |
|---|---|---|
| Development | Testing on dev devices | Specific devices |
| Ad Hoc | Testing on up to 100 devices | Specific devices |
| App Store | App Store distribution | All devices |
| Enterprise | Internal distribution | All devices |
Google Play Console Setup (Android)
Step 1: Create an App
- Go to Google Play Console
- Click Create app
- Fill in:
- App name: DodaBrowser
- Default language: English
- App or game: App
- Free or paid: Free
Step 2: Store Listing
- Short description: 80 characters
- Full description: Up to 4000 characters
- Screenshots: 2-8 screenshots (minimum 320px, maximum 3840px)
- Feature graphic: 1024×500px
- App icon: 512×512px (32-bit PNG)
- Content rating: Complete questionnaire
Building for Release
Android: App Bundle vs APK
# Build an Android App Bundle (recommended)
./gradlew bundleRelease
# Output: app/build/outputs/bundle/release/app-release.aab
# Build an APK
./gradlew assembleRelease
# Output: app/build/outputs/apk/release/app-release.apk
# Sign the app bundle (via build.gradle)
android {
signingConfigs {
release {
storeFile file("dodatech-keystore.jks")
storePassword System.getenv("KEYSTORE_PASSWORD")
keyAlias "dodatech"
keyPassword System.getenv("KEY_PASSWORD")
}
}
buildTypes {
release {
signingConfig signingConfigs.release
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
}iOS: Archive and Export
# In Xcode:
# 1. Product → Archive
# 2. Organizer window opens
# 3. Select archive → Distribute App
# 4. Choose: App Store Connect / Ad Hoc / Development
# 5. Upload or export .ipa
# Or using fastlane:
fastlane gym --scheme DodaBrowser --export_method app-storeVersioning
Semantic Versioning
1.2.3
↑ ↑ ↑
| | └── Patch (bug fixes)
| └──── Minor (new features, backward compatible)
└────── Major (breaking changes)Android versioning
// build.gradle.kts
android {
defaultConfig {
versionCode = 12 // Monotonic integer — always increase
versionName = "1.2.3" // User-visible version
}
}iOS versioning
// In Xcode project settings:
// Marketing Version: 1.2.3 (user-visible)
// Build Number: 12 (monotonic integer)
// Or in Info.plist
// CFBundleShortVersionString: 1.2.3
// CFBundleVersion: 12Release Tracks
flowchart TD
Dev[Development] --> Internal[Internal Testing]
Internal --> Alpha[Alpha / Closed Track]
Alpha --> Beta[Beta / Open Track]
Beta --> Production[Production]
Production -->|Hotfix| Beta
Beta --> Production
Google Play Tracks
| Track | Audience | Review Required | Availability |
|---|---|---|---|
| Internal | Up to 100 email addresses | No | Minutes |
| Closed | Custom list (email/Google Groups) | No | Hours |
| Open | Anyone with link | No | Hours-days |
| Production | All users | Yes | 1-3 days |
App Store Connect
| Distribution | Audience | Notes |
|---|---|---|
| TestFlight Internal | Up to 100 team members | No review |
| TestFlight External | Up to 10,000 testers | Beta App Review (usually quick) |
| App Store | All users | Full review (1-3 days) |
App Review Guidelines
Common iOS Rejection Reasons
- 2.1 — Crashes/Bugs: App crashes during review. Test thoroughly.
- 2.3 — Metadata: Screenshots show features the app doesn’t have.
- 3.1 — In-App Purchases: Using external payment for digital goods.
- 4.2 — Minimum Functionality: App is too simple (single webview).
- 5.1 — Privacy: No privacy policy or collecting data without consent.
Common Android Rejection Reasons
- Policy: Deceptive Behavior: Misleading app description or screenshots.
- Policy: Permissions: Requesting permissions that don’t relate to app function.
- Policy: Spam: Duplicate apps or keyword stuffing.
- Policy: Gambling: Real-money gambling without proper licensing.
Best Practices for Smooth Review
- Test your app on real devices (not just simulators)
- Provide demo accounts for review team
- Make sure “Sign in with Apple” is included if using social login
- Submit with all metadata complete
- Respond to review feedback within 24 hours
In-App Purchases
iOS (StoreKit)
import StoreKit
class PurchaseManager: NSObject, SKProductsRequestDelegate {
func fetchProducts() {
let request = SKProductsRequest(productIdentifiers: ["premium_monthly"])
request.delegate = self
request.start()
}
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
for product in response.products {
print("Product: \(product.localizedTitle) — \(product.price)")
}
}
}Android (Billing Library)
val billingClient = BillingClient.newBuilder(context)
.setListener { purchases, _ ->
for (purchase in purchases) {
if (purchase.purchaseState == Purchase.PurchaseState.PURCHASED) {
// Grant entitlement
unlockPremium()
}
}
}
.enablePendingPurchases()
.build()Common App Store Deployment Errors
1. Expired Certificates or Provisioning Profiles
Developer certificates expire after 1 year, distribution certs after 3 years. Renew before expiry or use Fastlane Match to automate management.
2. Mismatched Bundle ID
The bundle ID in Xcode must match App Store Connect. A mismatch causes “No matching provisioning profiles” errors.
3. Missing Privacy Policy
Apple requires a privacy policy URL for all apps since 2018. Google requires it for apps that collect personal data. Link to a proper policy page.
4. Version Code Not Incremented
Android requires a strictly increasing versionCode. Forgetting to increment causes upload rejection. Automate this in CI/CD.
5. 64-Bit Architecture Requirement
Since 2019, both stores require 64-bit support. iOS dropped 32-bit with iOS 11. Android requires 64-bit binaries for new apps.
6. Not Testing on Real Devices
Simulators/emulators don’t show real-world behavior (network, sensors, battery). Test on actual devices before submission.
7. Incomplete Metadata
Missing screenshots, descriptions, or privacy URLs blocks submission. Use Fastlane Deliver or Gradle Play Publisher to automate metadata upload.
Practice Questions
1. What’s the difference between an APK and an Android App Bundle?
APK is the legacy format containing all code for all device configurations. App Bundle (AAB) defers APK generation to Google Play, which delivers only the code/resources needed for the user’s specific device (smaller downloads).
2. Why does iOS require code signing?
Code signing proves the app’s authenticity (it came from a registered developer) and integrity (it hasn’t been modified since signing). Without it, anyone could distribute malware through the App Store.
3. What are the four release tracks in Google Play Console?
Internal (up to 100 testers), Closed (custom list), Open (anyone with link), and Production (all users). Each has different review requirements.
4. How do you handle in-app purchases for subscriptions?
In iOS, use StoreKit 2 with Product.SubscriptionInfo. On Android, use Billing Library 6+ with BillingClient.queryProductDetailsAsync(). Both require server-side receipt validation.
5. Challenge: Build a CI/CD deployment pipeline.
Create a Fastlane setup that: builds the app, increments version code, runs tests, uploads to TestFlight (iOS) / Internal Track (Android), and notifies the team on Slack. Handle certificate management with match.
FAQ
Try It Yourself
Deploy a test app:
- Create a simple “Hello World” app in both platforms
- Set up App Store Connect / Google Play Console
- Configure code signing
- Build a release version
- Distribute via TestFlight / Internal Testing track
- Install on a device and verify it works
What’s Next
You now know the complete deployment pipeline: code signing, build configuration, release tracks, and app review navigation. Automate the process with Fastlane or Gradle Play Publisher so deployment becomes a single command instead of a manual checklist.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro