Skip to content

Expert · Publishing to the stores and the web · topic 43 of 50 · 30 min

Preparing a release

Explanation

Before publishing, set a unique application ID (Android) and bundle identifier (iOS), the display name, launcher icons (flutter_launcher_icons helps) and a splash screen. The version line in pubspec.yaml, such as 1.0.0+1, sets the version name and build number; the build number must increase for every upload. Release builds can be obfuscated with --obfuscate --split-debug-info. Remove debug code and prepare a privacy policy.

Release versus debug

During development you run debug builds: slower, with hot reload, debug banners and extra checks. Users get release builds: compiled ahead of time to fast native code, smaller, and without debugging tools. Before your first release there is a checklist of things to set up once.

Identity: application ID and bundle ID

Every app has a unique identifier on each platform. On Android it is the applicationId (in android/app/build.gradle or build.gradle.kts), like com.sharmasweets.orders. On iOS it is the bundle identifier, set in Xcode. flutter create uses com.example.app_name; never publish with com.example. Choose your final IDs before the first upload, because they cannot be changed afterwards: a new ID means a new app.

Name, icon and splash

  • Display name: android:label in AndroidManifest.xml and CFBundleDisplayName in ios/Runner/Info.plist.
  • Launcher icons: each platform needs many sizes; the flutter_launcher_icons package generates them from one 1024 x 1024 image, including Android adaptive icons.
  • Splash screen: Android 12+ has a system splash API and iOS uses a launch screen; the flutter_native_splash package configures both from pubspec settings.

Versioning

yaml
version: 1.4.2+23
pubspec.yaml: 1.4.2 is the version name users see; 23 is the build number.

Flutter maps this to Android's versionName (1.4.2) and versionCode (23), and to iOS's CFBundleShortVersionString and CFBundleVersion. The build number must be higher than every build you uploaded before, or the stores reject the upload. A common habit: bump the version name for each release following MAJOR.MINOR.PATCH and increase the build number for every upload, even test builds.

bash
flutter build appbundle --build-name=1.4.3 --build-number=24
You can also override the version from the command line, which is handy in CI.

Obfuscation

Obfuscation renames classes and functions in the compiled code to meaningless names, making reverse engineering harder (not impossible). Flutter supports it for Android and iOS release builds. --split-debug-info stores the symbol files needed to read crash stack traces; keep them, or crash reports become unreadable.

bash
flutter build appbundle --obfuscate --split-debug-info=build/symbols
flutter build ipa --obfuscate --split-debug-info=build/symbols
Upload the symbols to your crash reporting tool (for example Crashlytics) for readable stack traces.
Careful: Obfuscation does not protect secrets. API keys and passwords inside an app can still be extracted. Keep secrets on your server.

Final checklist

  • Remove print statements with personal data, test buttons and debug-only shortcuts.
  • Point the app at production APIs, not your test server (use build flavors or --dart-define for environments).
  • Test the release build on real devices: flutter run --release.
  • Publish a privacy policy page if you collect any personal data (stores require a URL).
  • Check permissions: request only what you need, with clear explanations.
Think of it like this: Preparing a release is like preparing a shop for its grand opening: the signboard (name and icon) is final, the licence number (application ID) is registered, the price tags have version labels, and the staff-only notes are removed from the counter before customers walk in.

Common mistakes

  • Publishing with the default com.example ID: rejected by stores, and changing it later creates a new app.
  • Forgetting to increase the build number: "Version code has already been used".
  • Losing the --split-debug-info symbols: unreadable crash reports.
  • Testing only debug builds: release-only problems (like a missing INTERNET permission) reach users.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Preparing a release · 1/6

Debug ≠ Release

Users get release builds: fast, compiled ahead of time, without debug tools.

Prefer a video by a teacher? Find free videos on “flutter release preparation app icon splash version build number obfuscate” on YouTube ↗

In real life: A sweet shop app's first release

Before launching "Sharma Sweets Orders", the developer changes the IDs from com.example to in.sharmasweets.orders, generates icons with flutter_launcher_icons from the logo, sets version 1.0.0+1, builds with obfuscation and stores the symbols, tests the release build on two budget phones, and publishes a privacy policy page listing the phone number and address data the app collects.

Practice (0/3 done)

Task 1 · Question

pubspec.yaml has version: 2.1.0+15. What is the build number?

Task 2 · Question

Why keep the files produced by --split-debug-info?

Task 3 · Practice

Prepare one of your apps for release: choose final IDs, set the display name on both platforms, generate launcher icons with flutter_launcher_icons, set version 1.0.0+1, build a release with obfuscation and split debug info, and run it with flutter run --release on a real phone. Write a short privacy policy draft.

Quick quiz

Question 1

1.What is the Android application ID?

Question 2

2.Which package generates launcher icons for all sizes from one image?

Question 3

3.Does obfuscation keep API keys in the app safe?

Question 4

4.Which command runs the release build on a connected phone?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What is the Android application ID?

Answer: The app's unique identity on devices and Google Play

It cannot change after publishing.

Which package generates launcher icons for all sizes from one image?

Answer: flutter_launcher_icons

It creates Android and iOS icons.

Does obfuscation keep API keys in the app safe?

Answer: No; secrets in an app can still be extracted

Keep secrets on the server.

Which command runs the release build on a connected phone?

Answer: flutter run --release

Test exactly what users will get.

What is the benefit of an App Bundle for users?Related

Answer: Smaller downloads tailored to their device

Play delivers only what each device needs.

From Release builds, signing and the App Bundle

Which Xcode file should you open for a Flutter iOS project?Related

Answer: ios/Runner.xcworkspace

The workspace includes CocoaPods dependencies.

From Publishing on the Apple App Store

Why release to production with a staged rollout?Related

Answer: Problems affect only a small share of users before a full release

You can halt a bad rollout.

From Publishing on Google Play

What must you do after adding a new font in pubspec.yaml?Related

Answer: A full restart (hot reload is not enough)

Assets are bundled at build time.

From Images, icons, fonts and themes

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 3 more topics in “Publishing to the stores and the web” before its exam: Publishing on Google Play, Publishing on the Apple App Store, Flutter on the web and desktop.
  2. Module 11 exam: Publishing to the stores and the web · 12 questions · 25 min, without help. 4 topics of this module still to finish first.
  3. Then the next module, Flutter careers and interviews. 50 topics left in the course before the final exam.

← Previous: Integration tests and CI