First serious flutter app

I recently built my first mobile app using the Flutter framework. As a software engineer focused on web development in recent years, mobile apps have been on the periphery. React Native further brought these seemingly disparate worlds together more so than any previous attempts. I appreciated the declarative nature of React. Flutter, courtesy of Google, combines some of React’s strength with lessons from gaming engines. Flutter apps ship with an engine working with skia to power UIs. Powered by the Dart language, Flutter offers a declarative interface allowing developers to build widgets akin to React components. Given my experience with React, a Flutter app allowed me to start with a paradigm that was familiar and powerful while being exposed to a new toolset.

I built a podcasts management app, Netcasts OSS. The examples shown below are taken from this work.

Getting Started

Flutter documentation and plenty of easily available posts assist developers in creating their first “Hello, World!” app. I will instead focus on my personal developer experience. I have the perspective of a vim user comfortable with the command line.

Flutter, relative to native app development, is friendlier to terminal/vim users. If you are familiar with webpack builds, I can compare the experience of webpack development with hot reload. Developers can run a flutter process that supports hot reload while developing a terminal based editor like vim.

flutter run -t lib/main_$FLUTTER_ENV.dart

Google’s Dart is the language paired with Flutter. Learning dart, much like learning another one of the commonly used languages, comes with a minor learning curve.

As with any significant application, you will need a state management solution. Flutter widgets allow for state management local to the widgets. Following, the redux mentality, for more complex global state management, implementation of redux are available. Inherited widgets, scoped models, and the BLoC pattern are alternatives available to address state management with varying pros and cons.

What’s Easy?

If your UI needs are simple (as was the case for a podcasts app), the set of material/ios widgets available will get you most of the way to the “finish line”. On top of this, there are widgets available from the Flutter community that allow you to add flourishes like parallax effects. Flutter also has a set of plugins available that make features like sharing, audio playback, and simpler notifications easy to obtain.

What’s Missing

The depth of work available to Flutter apps does not quite match the work available to react-native developers. Specific to my example, I needed things like control over audio playback speed and local notifications with action buttons is still being worked on by others in the community. This will mean that you will have to start writing android and ios native code to start contributing.

Digging In Further

Once you have some work going, you will begin looking at a bigger picture, consider environment management, and occasionally encounter hitches where you will have to slowdown, reconsider, refactor, and perhaps optimize.

Environment Handling

You can specify the entrypoint file when running/build flutter apps with the -t option. This means that you can have multiple entrypoint files such as main.dart, main_dev.dart, and main_prod.dart. You should keep your app’s logic out of these entrypoint files to more easily continue these entrypoints. For example, here is my app’s main.dart:

import 'dart:async';

import 'package:hear2learn/app.dart';
import 'package:hear2learn/run_app.dart';

Future<void> main() async {
  final App app = App();
  await app.init(
    elasticHost: 'localhost:9200',
  );

  await start();
}

In the example, the entrypoint contains environment specific details and kicks off the work to the start function in run_app.dart.

Seeing a lagging UI?

If you encountering a lagging UI within your app, Flutter makes a convenient profiling tools available. Often times these tools will point to misuse of the main thread used to execute long running tasks blocking the main thread. Flutter’s compute method and isolates provide you the means of moving unnecessarily blocking computation out of the main thread. Finally, keep build methods light for performant apps.

flutter run -t lib/main_$FLUTTER_ENV.dart --profile

Releasing the app

I used a release branch to track keystore and other release specific details to which I would continuously merge master into. Flutter docs pretty much guide developers through the entire release process upto the release in the play store.

flutter build apk -t lib/main_prod.dart

© 2019. All rights reserved.