Working with CodePush for Over-the-Air Updates in Flutter

In modern mobile app development, providing frequent updates and bug fixes is crucial for maintaining user satisfaction and app quality. However, deploying updates through app stores can be time-consuming and requires users to download the entire app again. CodePush offers a more efficient solution: over-the-air (OTA) updates. This allows you to push updates directly to users’ devices without going through the app store review process. This guide will explain how to integrate CodePush into a Flutter application.

What is CodePush?

CodePush is a cloud service that enables developers to deploy mobile app updates directly to their users’ devices. It supports platforms like React Native, Cordova, and Flutter. CodePush streamlines the update process, allowing developers to release bug fixes, feature enhancements, and UI/UX improvements seamlessly.

Why Use CodePush in Flutter?

  • Instant Updates: Deploy updates directly to users without waiting for app store approval.
  • Improved User Experience: Users receive updates without having to download a new version from the app store.
  • Rapid Bug Fixes: Quickly address critical bugs and issues with minimal disruption to users.
  • Flexibility: Test updates with a subset of users before rolling them out to everyone.

How to Integrate CodePush in Flutter

Integrating CodePush in a Flutter application involves several steps:

Step 1: Set up a CodePush Account and Install CLI

First, sign up for a CodePush account on the App Center platform (formerly Microsoft App Center). Then, install the CodePush CLI (Command Line Interface) using npm:

npm install -g code-push-cli

Log in to your App Center account using the CLI:

code-push login

Step 2: Create a New App in App Center

In the App Center dashboard, create a new app for each platform you intend to support (e.g., iOS and Android). Note the app names, as they will be used later.

Step 3: Install the CodePush Flutter Plugin

Add the flutter_code_push plugin to your pubspec.yaml file:

dependencies:
  flutter_code_push: ^latest_version

Run flutter pub get to install the dependency.

Step 4: Configure CodePush in Flutter

Import the flutter_code_push package in your Dart code. Initialize CodePush in your app’s main function:

import 'package:flutter/material.dart';
import 'package:flutter_code_push/flutter_code_push.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Replace with your deployment key for each platform
  const String androidDeploymentKey = 'YOUR_ANDROID_DEPLOYMENT_KEY';
  const String iosDeploymentKey = 'YOUR_IOS_DEPLOYMENT_KEY';

  await FlutterCodePush.init(
    androidDeploymentKey: androidDeploymentKey,
    iosDeploymentKey: iosDeploymentKey,
    updateDialog: true,
    // Optional: Customize update dialog
    title: 'Update Available',
    mandatoryContinueTitle: 'Update and Restart',
    optionalIgnoreTitle: 'Later',
    optionalInstallTitle: 'Update'
  );

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'CodePush Demo',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State {
  @override
  void initState() {
    super.initState();
    FlutterCodePush.sync(); // Check for updates on app start
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('CodePush Demo'),
      ),
      body: Center(
        child: Text('Hello, CodePush!'),
      ),
    );
  }
}

Retrieve the deployment keys for each platform from your app’s dashboard on App Center and replace 'YOUR_ANDROID_DEPLOYMENT_KEY' and 'YOUR_IOS_DEPLOYMENT_KEY'.

Step 5: Set Up Platform-Specific Configurations

For Android, modify android/app/build.gradle to include CodePush:

android {
    // ...
    defaultConfig {
        // ...
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }
    
    // Add this block
    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            outputFileName = "app-${variant.name}-${defaultConfig.versionName}.apk"
        }
    }
}

dependencies {
    implementation "com.microsoft.codepush.bundle:codepush:latest_version"
}

For iOS, modify the Info.plist file in ios/Runner/Info.plist to include the CodePush deployment key:

CodePushDeploymentKey
YOUR_IOS_DEPLOYMENT_KEY

Step 6: Release Updates with CodePush

Once you’ve made changes to your Flutter application and want to deploy an update, use the CodePush CLI:

code-push release-flutter <appName> <platform>

Replace <appName> with the name of your app in App Center and <platform> with either android or ios.

code-push release-flutter MyAppAndroid android
code-push release-flutter MyAppIOS ios

The CodePush CLI bundles your JavaScript, HTML, CSS, and image assets, then pushes the update to the CodePush server.

Step 7: Testing Updates

To test the updates, run your Flutter application on a physical device or emulator. The app automatically checks for updates on startup, and if an update is available, it downloads and installs it.

Advanced CodePush Configuration

Custom Update Dialog

You can customize the update dialog by providing custom parameters to the FlutterCodePush.init method, such as changing the title and button labels:

await FlutterCodePush.init(
  androidDeploymentKey: androidDeploymentKey,
  iosDeploymentKey: iosDeploymentKey,
  updateDialog: true,
  title: 'New Version Available',
  mandatoryContinueTitle: 'Install Now',
  optionalIgnoreTitle: 'Later',
  optionalInstallTitle: 'Download'
);

Rollout Updates Gradually

CodePush allows you to roll out updates gradually to a percentage of your users. This helps you monitor the impact of the update before releasing it to everyone.

code-push release-flutter MyAppAndroid android -r 20%

This command releases the update to 20% of your users.

Conclusion

Integrating CodePush into a Flutter application provides a seamless and efficient way to deliver updates directly to users. By following the steps outlined in this guide, you can quickly deploy bug fixes, feature enhancements, and UI/UX improvements without the delays associated with app store reviews. Leveraging CodePush will enhance your development workflow and ensure a better user experience.