Skip to content
Blog

Product updates 2 min read

What's new in v2.0 of the Shorebird Code Push Package

Announcing the pre-release of pkg:shorebird_code_push v2.0.

Felix Angelov

Founding Engineer

We’re excited to announce a pre-release of version 2.0 of the shorebird_code_push package.

The shorebird_code_push package is a completely optional package that allows developers to customize the user experience of downloading and installing over the air updates with Shorebird. By default, Shorebird auto updates in the background but teams that want more control over when updates are downloaded and installed can use the shorebird_code_push package to programmatically interact with Shorebird’s updater.

Some common use cases for using shorebird_code_push are:

  • Reducing the number of restarts required from 2 to 1
  • Only sending updates to some fraction of your users
  • Forcing users to upgrade for critical fixes
  • Recording custom analytics about update installations/failures

What’s New

We’ve taken some time to re-imagine what the Dart API should look like when interfacing with the Shorebird updater and we’ve re-written the Dart API from the ground up.

The two main areas we focused on were:

  • ✨ Simplifying the public API
  • ❗️ Improving error reporting/handling

We really wanted package:shorebird_code_push to be simple and intuitive to use so v2 comes with a much smaller public API surface.

The first thing we did was rename the core class from ShorebirdCodePush to ShorebirdUpdater in order to better describe the purpose of the class.

import 'package:shorebird_code_push/shorebird_code_push.dart';

// Create an instance of the `ShorebirdUpdater`
final updater = ShorebirdUpdater();

We broke the public API into 3 main parts:

  1. Reading patch information
  2. Checking for updates
  3. Performing updates

Reading Patch Information

To get information about the current (installed) or next (downloaded) patches, you can use the readCurrentPatch or readNextPatch APIs.

@override
void initState() {
  super.initState();
  updater.readCurrentPatch().then((patch) {
    // The current patch is `null` when no patch is installed.
    print(patch?.number);
  });
}

Checking for Updates

To check for updates, you can use the checkForUpdate API:

Future<void> _checkForUpdate() async {
  // Check if there's an update available.
  final status = await updater.checkForUpdate();
  // If there is an update available, show a banner.
  if (status == UpdateStatus.outdated) showUpdateAvailableBanner();
}

checkForUpdate returns an UpdateStatus enum which provides much more information about the current state of the updater. You don’t need to write your own logic to determine what state the app is in anymore, the ShorebirdUpdater directly exposes it for you.

/// The current status of the app in terms of whether its up-to-date.
enum UpdateStatus {
  /// The app is up to date (e.g. running the latest patch.)
  upToDate,

  /// A new update is available for download.
  outdated,

  /// The app is up to date, but a restart is required for the update to take
  /// effect.
  restartRequired,

  /// The update status is unavailable. This occurs when the updater is not
  /// available in the current build.
  /// See also:
  /// * [ShorebirdUpdater.isAvailable] to determine if the updater is
  /// available.
  unavailable,
}

Performing Updates

Finally, if an update is available you can use the update API to perform the update.

Future<void> _downloadUpdate() async {
  try {
    // Perform the update (e.g download the latest patch).
    await updater.update();
    // Show a banner to inform the user that the update is ready and that they
    // need to restart the app.
    showRestartBanner();
  } on UpdateException catch (error) {
    // We now have much better insights into why an update fail.
    showErrorBanner(error.message);
  }
}

If the update was unsuccessful, you can now programmatically catch the UpdateException and have much more information about what went wrong.

The UpdateException includes a human-readable message describing the error as well as an UpdateFailureReason:

/// The reason a call to [ShorebirdUpdater.update] failed.
enum UpdateFailureReason {
  /// No update is available.
  noUpdate,

  /// The update failed because the patch could not be downloaded.
  downloadFailed,

  /// The update failed because the patch failed to install.
  installFailed,

  /// The update failed for an unknown reason.
  unknown,
}

To see the latest version in action, check out the Shorebird Code Push Example or the Flutter & Friends Conference App.

Get Started

You can try out the new version now by adjusting your pubspec.yaml to use the pre-release and re-releasing a new version of your application using the revision of Flutter 3.24.4.

dependencies:
  shorebird_code_push: ^2.0.0-dev.2

We’d love to hear your feedback! If there’s anything you’d like to see adjusted or improved, please let us know by filing an issue.

All posts
  • Product updates 2 min read

    Orgs at Shorebird just got better

    Shorebird now has one kind of organization. Your personal org works like any other org, and org membership replaces app collaborators.

    Wesley Peck

    Lead Product Manager

  • Product updates 5 min read

    Your CI shouldn't run on someone's personal key

    Service accounts give your release pipeline its own identity in your organization, with a fixed role and keys that keep working as your team changes. On GitHub Actions, you can drop the stored key entirely.

    Abhishek Doshi

    Developer Relations Engineer

  • Product updates 4 min read

    Shorebird's got your back: patch signing is now on by default

    A compromised certificate authority put apps that bundle their own trust list at risk. Here's how it affects Shorebird apps, and why every new release is now signed by default.

    Wesley Peck

    Lead Product Manager

Ship your first patch today.

Install the CLI, create a release and send a patch. Free for 5,000 patch installs a month.

Larger team? Talk to sales