Flavoring Flutter

If you read my last Flutter story you know that we had a problem configuring flavors in Flutter.

Why to use flavors

Working alone as a hobbyist android developer I never looked at flavors/build-config. 
I did not need them, I was the only person of my team and the only stakeholder ¯\(ツ)

Here at Iakta the team is bigger and we have many customers, so if something goes wrong you cannot just yell at the mirror.

Me angry with me

Flavors are just comfortable. They let you define some build configuration and switch them as you want. For example you could have one flavor for development, and one for production. You can set different url for api calls or different icons and app names. With a click you’re ready to develop or to release your great application.

We use a lot flavor configurations, not only for comfort, but also to be sure to deploy the right version of the app. We just set different icons and sometimes even app theme to be sure not to release an app with an api url pointing to local or staging machines. That would be very dangerous and shameful.

Me ashamed

Usually we use from 3 to 5 different flavor per app (development, production, staging, demo..)

Flavors in Flutter

When it comes to Flutter, flavors are easy to implement, but if you don’t know android flavors and iOS schema you can have some problem. I used to use android buildConfigs and iOS targets and so it was not so straightforward.

Flutter cli has an option for flavors, so you can run/build your app using flavors:

flutter build --flavor development

These are mapped to android productFlavors and iOS schema.

Android productFlavors

Regarding android the productFlavors are defined in the app gradle module.

An example of gradle file with productFlavors

As you can see is pretty straightforward and you can set different application id suffixes.

Note that flavor names have to be the same as the cli flutter command.

Now for example you can add icons based on flavor type.

Adding icons
Different apps with different icons

iOS schema

In iOS is a bit trickier.

After some time I think this is the easiest way to do this.

Create in the ios/Flutter folder a configuration file for every flavor, including the Generated.xcconfig file and setting FLUTTER_TARGET to the main file required by the target.

xcconfig file example

Here you can also define some environment variables you can need in you platform-side code. For example some url.

Then create a new scheme for every flavor.

Remember to check the shared checkbox in the dialog.

check the shared checkbox

Now select the Runner project and add the configurations you need selecting as configuration file the one created before.

Note that you need to have two configurations for each flavor named with Release-[flavorName] and Debug-[flavorName]. Names are really important for flutter matching reasons.

A flavor plist file is also required to set things like bundleId or the variables defined in the xcconfig file.

To link the plist files to the configurations go to the Runner target

Regarding the icons they can be set in the Runner target in the Asset Catalog App Icon Set Name option.

Done!

Flavors in dart code

How to use flavors in dart code? There is no way to get the flavor in flutter code.

We found that the only way to solve this problem is to use Flutter targets.

When running your app you are able to choose the main file using the cli option -t (or — target):

flutter build --flavor development -t lib/main-dev.dart

In this way the entry point of the app is set to main-dev.dart.

How to exploit this command? The easiest thing is to create a config.dart file with a Config class and a Flavor enum.

Using the appFlavor static field we’re able to set different flavors in different main files.

In this way it’s easy to know if we’re in the dev or production version.

For example here we can show different messages and icons based on flavor type. As easy as this!

So this would be our final configuration: two main files and a configuration file.

Hooray!

Yes, I know. It’s a mess, but it’s a “una tantum” thing that can save you time and life.

You can find the example repository at https://github.com/iakta/flutter_flavors.

If I made something wrong or I missed something just write me. Comments and considerations are more than welcome!

Bye, a presto!


Originally published at en.iakta.org.