Deploying a Flutter app to both platforms simultaneously is one of Flutter's biggest value propositions. But the process has enough platform-specific quirks to trip up even experienced developers. Here's the complete guide.
Prerequisites
Before you start, make sure you have:
flutter doctoriOS Setup
1. Configure Signing
Open your project in Xcode:
open ios/Runner.xcworkspaceIn Xcode:
2. Configure Info.plist
Add required permissions:
<key>NSCameraUsageDescription</key>
<string>This app needs camera access for photos</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs photo library access</string>3. Build for iOS
flutter build ios --releaseThen archive and upload through Xcode or use:
flutter build ipa --releaseAndroid Setup
1. Configure build.gradle
android {
defaultConfig {
applicationId "com.yourname.yourapp"
minSdkVersion 21
targetSdkVersion 34
versionCode 1
versionName "1.0.0"
}
}2. Generate Keystore
keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload3. Build for Android
flutter build appbundle --releaseThe AAB file goes to Google Play, APK for direct distribution.
CI/CD with GitHub Actions
Automate both builds:
name: Deploy
on:
push:
tags: ['v*']
jobs:
ios:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@v2
- run: flutter build ipa --release
- uses: apple-actions/upload-testflight-build@v1
with:
app-path: build/ios/ipa/*.ipa
android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@v2
- run: flutter build appbundle --release
- uses: r0adkll/upload-google-play@v1
with:
serviceAccountJsonPlainText: ${{ secrets.PLAY_STORE_KEY }}
packageName: com.yourname.yourapp
releaseFiles: build/app/outputs/bundle/release/app-release.aab
track: productionPost-Deployment
After both stores approve your app:
The whole process takes about 2-3 hours for the first time. After that, tagging a release triggers automatic deployment to both stores.