Friday, November 25, 2022
HomeWeb DevelopmentFacilitate app updates with Flutter upgrader

Facilitate app updates with Flutter upgrader


A easy alert immediate or card is displayed when a more moderen app model is out there within the Google Play Retailer or Apple App Retailer. Most customers reap the benefits of this auto-upgrade characteristic to keep away from having to replace every app individually on their telephones.

Nevertheless, there are occasions when an app must be up to date extra rapidly than common, and the consumer have to be notified straight slightly than counting on a retailer alert. This direct notification can also be useful for reaching people who find themselves not subscribed to auto updates.

This situation is particularly vital when you’re following a launch early, launch typically philosophy; incessantly including new content material and options to your app, and releasing new variations at a reasonably excessive cadence.

Having a number of variations of your app on the market could cause model fragmentation points, which is a gigantic downside for app improvement. Luckily, there’s an ideal Flutter plugin that helps you alert customers and immediate them to replace their app to the most recent model: upgrader.

On this tutorial, we’ll focus on how upgrader works and we’ll exhibit totally different methods that can be utilized to deal with app model upgrades.

Soar forward:

Stipulations

To comply with together with this information, it’s best to have the next:

  • Fundamental data of Flutter, stateful widgets, and bundle versioning
  • Working data of pushing cellular apps to the Google Play Retailer and Apple App Retailer

Getting began

The tutorial portion of this text will use the Days With out Incidents (DWI) app to exhibit ideas. DWI is an easy incident counter app that helps a number of counters, kinds, and a easy consumer interface.

To comply with alongside, obtain the open supply code obtainable through GitHub and guarantee you’re utilizing Flutter v3.0+.

Open the challenge along with your most well-liked IDE, and keep in mind to get the dependencies with flutter pub get.

Right here’s a fast rundown of some vital recordsdata try to be conscious of:

  • lib/primary.dart: Normal primary file required for Flutter tasks
  • lib/core: Core widgets and utilities shared between two or extra options
  • lib/options: Makes use of characteristic grouping to summary totally different elements of the UI
  • packages: Accommodates the information and area layers

To raised perceive the necessities, you can even try this GitHub pull request. It has all of the modifications required to deal with app updates and model restrictions by yourself.

Understanding how upgrader works

As talked about beforehand, model fragmentation will happen when there are too many variations of an app out there. Every model might have totally different options, gadget help, display help, and even API variations. Your infrastructure and providers might want to help all these variations, leading to dearer enterprise operations.

So, what’s the answer?

There are three issues you are able to do to cut back the impression of model fragmentation:

  1. Have a manageable record of variations that you simply help
  2. Implement a minimal model you’re supporting

  3. Information the consumer by way of updates if their app shouldn’t be working the most recent model

That is the place upgrader turns out to be useful; it helps you set in place all these mechanisms in your app with out an excessive amount of overhead.

upgrader is a Flutter plugin that helps handle the consumer’s put in model of your app. It lets you examine if the consumer has the most recent model put in and if they don’t, it guides the consumer to put in it through an app retailer with a dialog or widget.

The plugin can even implement a minimal app model and gives inbuilt help RSS feeds with the Appcast customary utilized by Sparkle (we’ll focus on this additional later on this article).

Sufficient chit-chat; it’s time you dive into some code!

Displaying alerts if the app is outdated

One of the frequent use circumstances for upgrader is to show a dialog field when the presently put in app is outdated in comparison with the shop itemizing.

To do that out, open the lib/options/time_counter/pages/counter_page.dart file and alter the CountersPage construct to the next:

@override
Widget construct(BuildContext context) {
  return Scaffold(
    appBar: const DWIAppBar(),
    physique: UpgradeAlert(
      little one: const SafeArea(
        little one: _Body(),
      ),
    ),
  );
}

UpgradeAlert can wrap a widget, permitting you to put it as a wrapper of the physique property and never have to fret about guide checks to the model.

N.B., keep in mind so as to add this import on the high of the file: import 'bundle:upgrader/upgrader.dart';

In the event you construct and run the app proper now, you’ll see the next:

Flutter Alert for Outdated App

The plugin gives restricted model customization for the dialog field. The dialogStyle property in Upgrader has two totally different choices: UpgradeDialogStyle.cupertino and the default UpgradeDialogStyle.materials.

Change the construct once more and alter the model to be cupertino, like so:

@override
Widget construct(BuildContext context) {
  return Scaffold(
    appBar: const DWIAppBar(),
    physique: UpgradeAlert(
      upgrader: Upgrader(dialogStyle: UpgradeDialogStyle.cupertino),
      little one: const SafeArea(
        little one: _Body(),
      ),
    ),
  );
}

Now, construct and run the app. It ought to look one thing like this:

Flutter Alert with Diaglog Box for Outdated App

Subsequent, go forward and go away the construct because it was at first:

@override
Widget construct(BuildContext context) {
  return const Scaffold(
    appBar: DWIAppBar(),
    physique: SafeArea(
      little one: _Body(),
    ),
  );
}

One other frequent situation is having an indicator within the UI to show that the put in model of the app shouldn’t be updated. Once more, the plugin has a very good implementation for this through UpgradeCard.

Let’s add UpgradeCard and see the way it appears to be like. Open the lib/options/time_counter/widgets/counter_list.dart file and add the next code above Expanded in order that it’s displayed on the high of the display:

UpgradeCard(),

In the event you construct and run the app, that is the way it ought to look:

Flutter Update App Alert with UpgradeCard

As you may see, UpgradeCard shows a card styled with Materials Design, it makes use of the identical content material as UpgradeAlert however exhibits it inline as a substitute of with a dialog field. For the reason that card doesn’t look nice, on this case, go forward and delete the code you simply added (delete line 81). We’ll contemplate another choices as a substitute.

Now, generally these two inbuilt behaviors (UpgradeAlert and UpgradeCard) are usually not sufficient when it comes to consumer expertise. For instance, you could wish to present an IconButton when there’s an replace obtainable for the app.

Let’s give this instance a attempt.

You’ll have to create a brand new widget that may work like UpgradeAlert and UpgradeCard. Actually, when you take a better have a look at the library’s code, you’ll discover that each lengthen UpgradeBase which can make issues a bit simpler.

Begin by making a lib/core/widgets/upgrade_widget.dart file and add the next code:

import 'dart:developer';

import 'bundle:flutter/materials.dart';
import 'bundle:upgrader/upgrader.dart';

/// Defines a builder operate that lets you create a customized widget
/// that's displayed in a similar way as [UpgradeCard]
typedef UpgradeWidgetBuilder = Widget Perform(
  BuildContext context,
  Upgrader upgrader,
);

/// A widget to show by checking upgrader data obtainable.
class UpgradeWidget extends UpgradeBase {
  /// Creates a brand new [UpgradeWidget].
  UpgradeWidget({
    Key? key,
    Upgrader? upgrader,
    required this.builder,
  }) : tremendous(upgrader ?? Upgrader.sharedInstance as Upgrader, key: key);

  /// Defines how the widget will probably be constructed. Permits the implementation of customized
  /// widgets.
  last UpgradeWidgetBuilder builder;

  /// Describes the a part of the consumer interface represented by this widget.
  @override
  Widget construct(BuildContext context, UpgradeBaseState state) {
    if (upgrader.debugLogging) {
      log('UpgradeWidget: construct UpgradeWidget');
    }

    return FutureBuilder(
      future: state.initialized,
      builder: (BuildContext context, AsyncSnapshot<bool> processed) {
        if (processed.connectionState == ConnectionState.executed &&
            processed.information != null &&
            processed.information!) {
          if (upgrader.shouldDisplayUpgrade()) {
            if (upgrader.debugLogging) {
              log('UpgradeWidget: will name builder');
            }
            return builder.name(context, upgrader);
          }
        }

        return const SizedBox.shrink();
      },
    );
  }
}

Right here’s a fast overview of the code we simply added:

Within the above code, UpgradeWidget is a wrapper widget that implements the identical primary conduct that UpgradeCard and UpgradeAlert share. It extends UpgradeBase and does primary checks when the custom-made construct is executed. It should help you wrap any widget and show details about updating the app if wanted.


Extra nice articles from LogRocket:


UpgradeWidget receives an elective Upgrader implementation but in addition has the default implementation, so each the UpgradeCard and UpgradeAlert work. Making the customized widget use the identical rules lets you maintain interoperability between your customized widget and the library’s API.

UpgradeWidgetBuilder is an alias for the builder operate used to render the content material widget. It has Upgrader as a parameter as a result of that may present entry to the knowledge required for constructing a customized widget. We’ll focus on this in additional element somewhat later on this article.

Now that you simply’ve arrange a reusable UpgradeWidget, open the lib/core/widgets/dwi_appbar.dart file and duplicate this code on the backside of the file:

class _UpdateButton extends StatelessWidget {
  const _UpdateButton({
    Key? key,
  }) : tremendous(key: key);

  @override
  Widget construct(BuildContext context) {
    return UpgradeWidget(
      upgrader: Upgrader(
        //! This can be a little bit of a hack to permit the alert dialog to be proven
        //! repeatedly.
        durationUntilAlertAgain: const Length(milliseconds: 500),
        showReleaseNotes: false,
        showIgnore: false,
      ),
      builder: (context, upgrader) => CircleAvatar(
        little one: IconButton(
          onPressed: () {
            upgrader.checkVersion(context: context);
          },
          icon: const Icon(Icons.add),
        ),
      ),
    );
  }
}

_UpdateButton is a handy, non-public widget that enables us to set the conduct for our customized UpgradeWidget. On this case, the thought is to showcase the upgrader alert dialog when the IconButton is tapped. This may be achieved by calling checkVersion and passing the context as a parameter; the plugin will take over when the operate known as and a brand new UpgradeAlert needs to be displayed.

For higher readability, the showReleaseNotes and showIgnore flags are set to false since each components take up an excessive amount of house within the UI. Additionally, DWI app customers are accustomed to easy consumer expertise, so you may skip exhibiting these for now.

One final caveat is that at any time when the consumer faucets Later in UpgradeAlert, the library shops a timestamp to keep away from exhibiting the dialog field too typically or at undesired occasions. It should solely reshow the dialog field as soon as a while has handed (the default is three days).

You’ll have to bypass this characteristic for the DWI app and present the dialog field each time the consumer faucets on the replace IconButton. To perform this, we’ll override the default durationUntilAlertAgain with a Length of 500ms. This manner, the library will mark the dialog field as prepared because it’s closed by the consumer.

N.B., it is a considerably hacky answer, as a result of it wouldn’t be wanted if the library trusted us to show the alert dialog at any level we desired. Sadly, on the time of writing, upgrader doesn’t provide inbuilt help for this type of conduct.

Now, let’s add _UpdateButton(), to actions simply above _AddCounterButton. Additionally, ensure you add the corresponding imports for the library on the high of the file:

import 'bundle:dwi/core/widgets/widgets.dart';
import 'bundle:upgrader/upgrader.dart';

After you construct and run, it’s best to see the next:

Flutter Update App Alert Created with UpgradeAlert

Update App Alert Created with Flutter's Upgrader

Implementing a minimal model within the app

One other nice characteristic of upgrader is its means to implement a minimal app model just by including predefined textual content to the outline within the app shops or by defining a minimal app model inside Upgrader, like so:

Upgrader(
  minAppVersion: '3.0.0',
),

In the event you’re wanting to make use of app retailer descriptions, maintain the next codecs in thoughts:

  • Format for the Google Play Retailer (Android apps): [Minimum supported app version: 1.2.3]
  • Format for the Apple App Retailer (iOS apps): [:mav: 1.2.3]

Utilizing the above textual content format will outline the minimal app model as 1.2.3. Which means that earlier variations of this app will probably be compelled to replace to the most recent model obtainable.

Controlling your individual model listings

An vital restrict of upgrader is that its default conduct leverages the present Apple App Retailer and Google Play Retailer listings of your app, which means:

  1. If Google or Apple decides to cease displaying the app model or limits the allowed description codecs then upgrader‘s default conduct will cease working
  2. In case your app shouldn’t be distributed through public shops, upgrader won’t work as meant out of the field

  3. You aren’t in charge of the record of variations that you simply help and there’s no historical past about them

To resolve this, upgrader gives help for working with Appcast, which relies on the Sparkle framework by Andy Matuschak. Sparkle is a extensively used customary that lists all of the variations of an app with an XML format. The Appcast feed describes every model of an app and offers upgrader with the newest model.

Right here’s an instance from the Sparkle documentation exhibiting how an Appcast file might look:

<rss xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/components/1.1/" model="2.0">
  <channel>
    <title>Sparkle Take a look at App Changelog</title>
    <hyperlink>http://sparkle-project.org/recordsdata/sparkletestcast.xml</hyperlink>
    <description>Most up-to-date modifications with hyperlinks to updates.</description>
    <language>en</language>
    <merchandise>
      <title>Model 2.0</title>
      <hyperlink>https://sparkle-project.org</hyperlink>
      <sparkle:model>2.0</sparkle:model>
      <description>
      <![CDATA[ <ul> <li>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</li> <li>Suspendisse sed felis ac ante ultrices rhoncus. Etiam quis elit vel nibh placerat facilisis in id leo.</li> <li>Vestibulum nec tortor odio, nec malesuada libero. Cras vel convallis nunc.</li> <li>Suspendisse tristique massa eget velit consequat tincidunt. Praesent sodales hendrerit pretium.</li> </ul> ]]>
      </description>
      <pubDate>Sat, 26 Jul 2014 15:20:11 +0000</pubDate>
      <enclosure url="https://sparkle-project.org/recordsdata/Sparklepercent20Testpercent20App.zip" size="107758" kind="utility/octet-stream" sparkle:edSignature="7cLALFUHSwvEJWSkV8aMreoBe4fhRa4FncC5NoThKxwThL6FDR7hTiPJh1fo2uagnPogisnQsgFgq6mGkt2RBw=="/>
    </merchandise>
  </channel>
</rss>

This file needs to be hosted on a server accessible to anybody who makes use of the app. It additionally may be auto generated through the launch course of, or you may manually replace it after a launch is out there within the app shops.

Utilizing upgrader with an Appcast is comparatively easy as effectively. Right here’s an instance from the library’s documentation:

import 'bundle:flutter/materials.dart';
import 'bundle:upgrader/upgrader.dart';

void primary() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({
    Key key,
  }) : tremendous(key: key);

  @override
  Widget construct(BuildContext context) {
    last appcastURL =
        'https://uncooked.githubusercontent.com/larryaasen/upgrader/grasp/check/testappcast.xml';
    last appcastConfig = AppcastConfiguration(url: appcastURL, supportedOS: ['android', 'ios']);

    return MaterialApp(
      title: 'Upgrader Instance',
      residence: Scaffold(
          appBar: AppBar(
            title: Textual content('Upgrader Instance'),
          ),
          physique: UpgradeAlert(
            Upgrader(appcastConfig: appcastConfig),
            little one: Middle(little one: Textual content('Checking...')),
          )),
    );
  }
}

Nice work! Now you realize precisely the best way to maintain customers working the most recent model of your app and also you’re additionally conscious of the principle “gotchas” that you simply would possibly discover alongside the best way.

What’s subsequent?

On this article, we reviewed totally different methods for dealing with Flutter app updates utilizing upgrader. You possibly can view an entire record of all of the modifications wanted in this PR of Days With out Incidents.

I hope you loved this tutorial. In the event you discovered it helpful, please contemplate sharing it with others. I’ll be comfortable to deal with any questions left within the feedback part beneath.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments