4 min read
SMF 0.8: Flutter flavors, CI and a REST client
SMF 0.8 gives every app Flutter flavors for dev, staging and prod, and adds modules for CI on GitHub Actions, a REST client, an app icon and a splash screen.
By Yevhen Beshkarov
- release
- ci
- firebase
Say My Frame (SMF) generates Flutter apps from independent modules. Version 0.8 is out on pub.dev, and it covers what an app needs before it goes to the stores: Flutter flavors, CI, a REST client, and an icon and a splash screen that are not the ones of Flutter.
dart pub global activate smf_flutter_cli
smf create my_app -m home,bottom_tabs,material_theme,gen_l10n,dio,github_actions,launcher_icons,native_splash
As before, you get a regular Flutter project with no SMF package in its dependencies, and SMF never touches it again.
Flutter flavors in every app
Every app now has dev, staging and prod. You don't ask for them, and no package stands behind them: they are plain Gradle and Xcode settings. Each flavor has its own id and its own name, so all three sit next to each other on one phone.

flutter run builds dev. So does any other flutter command without --flavor, in release mode too, which means flutter build appbundle gives you a release of your dev app. A build for a store always names the flavor. In an app with values in .env, it takes those too:
flutter build appbundle --flavor prod --dart-define-from-file=.envWith firebase_core, each flavor has its own Firebase apps, in one project or in several. In a terminal, smf create configures dev, and each other flavor takes one command:
dart tool/configure_firebase.dart staging --project=my-app-staging.env is the one thing that does not follow the flavor. There is one file, and a command takes what the file has when it runs. On your machine you change the values by hand, and in CI the job writes the file for the environment that it builds. The guide to flavors has the rest, such as adding a fourth flavor.
CI on GitHub Actions
github_actions adds .github/workflows/ci.yml. Each push to a branch checks the format and runs the analyzer and the tests, with nothing to set up first.
A build of the Android app runs on request, for the environment that you pick, with the values of .env from the variables of that environment on GitHub:
gh workflow run ci.yml -f environment=stagingThe CI guide lists the commands and where the variables go.
A REST client with its address in .env
dio gives the app appRest, a client that reads the address of your API from REST_BASE_URL in .env:
final response = await appRest.get('notes', query: {'page': '1'});No screen of the app makes a request on its own, since the client is there for the code that you add. What it does for that code is the part I didn't want to leave to each app:
GETandHEADrepeat after a connection that failed and after 429, 502, 503 and 504. Other methods never repeat, since a repeatedPOSTmay do its work twice.- In an app with sign-in, the client adds the token of the user, gets a new one once after a 401, and takes the token away on a redirect to another origin.
- A call fails only with a
RestFailure, which has a closed set of reasons.
The REST guide covers the rest.
An app icon and a splash screen
launcher_icons and native_splash replace the logo of Flutter and the white launch screen with the mark of SMF, and the splash screen has a variant for the dark mode of the device. To use your own, replace the images in assets/branding/ and run:
dart tool/update_app_icon.dart
dart run flutter_native_splash:createThe guide to the icon and the splash screen gives the sizes of the images.
Upgrading from 0.7
- Apps generated by 0.7 stay as they are, since SMF generates an app once.
- If you write modules,
smf_contractschanged: a provider of the app entry writes the flavors into its native projects, and a provider of sign-in implementsuserToken. - A module that reads
lib/firebase_options.dartneeds an update, since each flavor now haslib/firebase_options_<flavor>.dart.
The full list is in the release notes of SMF 0.8.0 on GitHub.
What comes next
Next on my list are the rating of the app in the stores, reviews, remote config and ads. There are no dates: SMF is a side project. If you have a module in mind, tell me on Discord or in GitHub Issues.
SMF generates Android and iOS apps for Flutter 3.44 or newer and Dart 3.12 or newer. The documentation starts with installation and your first app, and the code is on GitHub.