I last looked at Flutter when it had just come out of Beta. Back then it already showed a lot of promise, but quite a number of native features had to be accessed via hybrid implementations of Flutter and the native platform. This required writing Dart for Flutter, Java / Kotlin for Android and Objective C / Swift for iOS.
Fast forward to today; a year has passed and currently there are over 4000 libraries that can be used with Flutter apps. Medium, Youtube and StackOverflow are — dare I say it, overflowing — with articles on how to achieve a wide variety of things with Flutter. There are multiple email lists dedicated to Flutter, here and here etc. Flutter SDK is the second fastest growing project on GitHub. All this points to a thriving community eager to share, grow and improve Flutter.
With all that, the time seemed right for me to look at specific requirements that will inform on whether or not Flutter and its library package ecosystem is ready to build Enterprise apps.
These requirements have come from areas that have needed particular attention in enterprise Android apps I have worked on. Not meeting some of these requirements would have become showstoppers for those apps.
My aim here is to find at least one Flutter solution for each requirement, hopefully to show that Flutter is now ready to build Enterprise apps with little to no hybrid coding required. You may have unique requirements beyond these so of course your results may vary!
The requirements I have selected have been categorised into the following areas:
- Development environment
- User Interface
- Access to hardware features
- Miscellaneous requirements
For each requirement, I have provided links as a starting point for further detailed exploration. With so many areas to cover, only brief summaries are included in this blog. It is assumed that the reader is already familiar with the basic features of Flutter. With that said, let’s get started!
Enterprise apps need to have architectures that allow for clear separation of concerns into layers to allow for, amongst other things:
- large teams of developers to work on the codebase simultaneously
- use of well documented design patterns leading to
- easier understanding of a wide range of app features
This leads to better productivity across the various skill levels of a diverse team of developers.
Flutter provides simple and secure networking to web resources, local storage, Sqlite databases, and access to hardware via library plugins.
State management is central to Flutter app architecture and the latest recommendation from Google of using the Provider framework, is easy to understand and build on. Other state management approaches such as Redux, BLoC, InheritedWidget, setState etc are also available and they can co-exist with each other, within reason.
Dependency Injection is a design pattern to make code units as independent and reusable as possible. It also makes code easier to unit test. GetIt locator is a simple to use DI library and works with the state management framework (such as Provider) to provide the separation of the app layers.
If Dart’s streams and async package aren’t sufficient for your asynchronous programming needs, ReactiveX is a popular style of asynchronous programming based on observable streams of events. RxDart integrates well with Flutter and state management frameworks.
Background processing allows for computationally intensive work to be performed in the app whilst maintaining UI responsiveness. Dart’s Isolates are the (slightly complicated) basis of performing work on background threads and the compute wrapper function simplifies Isolates for the most common use cases. Depending on the complexity of your requirement for background processing, native platform features may need to be adopted, beyond just a pure Dart implementation. See the first link for details.
JSON serialisation / deserialisation is essential to any RESTful client, common to most Enterprise apps. This link provides options from manual to code generated solutions.
Navigation and back stack management is a basic requirement, however there may be an app specific requirement to maintain multiple back stacks across multiple tabs in a bottom navigation enabled app, common in the iOS user experience.
Deep linking provides navigation from a website or push notification, to launch to specific areas within the app.
SQLite can be used to work with larger amounts of structured data.
App permission based read/write access to each platform’s file system is provided.
Push notification at the Enterprise level normally requires back end integration eg. informing the user that a credit card payment is overdue. Firebase messaging is one such solution. For local notifications based on a schedule or other data with criteria that can be triggered entirely on device, this library can be used.
Developers can choose between Android Studio / IntelliJ and Visual Studio Code for their Flutter IDE as all three are very well supported on Mac, PC, Linux, and Chromebook. Building, device deployment, debugging, and performance profiling, can all be achieved within these IDEs, as well as from the command line. For native iOS platform development / deployment, Xcode on a Mac is required.
Scalability: Flutter apps are inherently scalable as it is based on the Dart ecosystem which imports Dart packages to provide the functionality of external libraries. Flutter projects can be refactored into Flutter Dart packages, providing another way to split up the work for a large team of developers on an Enterprise app.
Testability: every Flutter widget and non-UI code artefact can be tested using one of the three test frameworks provided with Flutter: Unit Test, Widget Test, and Integration Test. This allows for maximum test coverage, limited only by available time and resourcing. Totally self-contained integration tests running against an in-app mock web server are possible using mock_web_server. A self-contained (ie. no web requests go outside the app) demonstration version of the app is also possible using this mock web server, if a way to switch between web server endpoints is provided. For instance you could switch between a mock, test environment and pre-production test environment in the debug build of your Enterprise app.
Continuous Integration / Continuous Delivery: Flutter uses the underlying Android and iOS toolset to deploy apps to the Google Play store or the Apple App store, so will coexist with any existing Enterprise mobile CI / CD set up. For new projects, CI /CD solutions tailored for Flutter are worth investigating, such as here and here.
It’s important to note that whilst a Flutter developer can spend most of her time in the Flutter / Dart environment, at the end of the day Flutter apps get deployed to Android and iOS devices. As a result there is no getting around the need to learn some aspects of the underlying native platforms, especially around deployment. Knowledge of how to build and sign apps and provisioning profiles etc is essential to implementing a successful Flutter app. Debugging in each native platform and learning how to read the two very different platforms’ stack traces, is another essential Flutter developer skill.
Enterprise mobile apps should be very focussed on providing an excellent user interface, and Flutter comes with a comprehensive set of highly accurate renditions of both Android (Material widgets) and iOS (Cupertino widgets).
Page transitions is an example of how navigation between app pages with animation can be achieved, in case there is requirement for maximising UI pop.
Paging / infinite scrolling list views are a common requirement when there are large amounts of data to be displayed to the user, without using up large amounts of device memory. Here is one of many tutorials on how to meet this requirement.
Access to Google Maps and Apple Maps is available.
Access to platform webviews is available, although it’s in developer’s preview state with some caveats.
Internationalisation is supported.
Accessibility is supported. Having worked on native Android accessibility, some accessibility features can be difficult and/or costly to implement across a whole app, so if you have any specific requirements in this area, it pays to perform proof-of-concepts to ensure correct operation of your accessibility requirement.
A chart library provides an easy way to visualise data sequences as bar graphs, pie and line charts etc.
Access to hardware features
It’s sometimes important, even a showstopper requirement, for an Enterprise mobile app to be able to access device hardware features, such as:
Security is paramount in Enterprise apps. It is a very broad topic that I will narrow down into a few specific topics for the purposes of keeping this blog down to a manageable size. The assumption is that Flutter builds on the Android and iOS app sandbox environments, so each Flutter app has the inherent security of native Android and iOS apps including the ability to communicate with external websites securely via https.
Essential requirements like authentication are well catered for. Simple Auth supports integration to the following authentication providers (from their documentation):
- Azure Active Directory
- Microsoft Live Connect
- Any standard OAuth2/Basic Auth server.
Amazon also provides their own Cognito SDK.
Difficulty of reverse engineering: Flutter Dart code compiles down to ARM binary code so it is slightly more challenging to reverse engineer than Android byte code. This can be further “enhanced” by using a technique such as code obfuscation. Code obfuscation can be a polarising topic — for some organisations it’s a must-have whilst others eschew it as providing a false sense of security. I won’t wade into the debate but simply note that Flutter Dart code can be obfuscated. This is separate to Android code which has its own obfuscation capabilities. There are also third party obfuscators for iOS native code eg. here, here etc. Note that the Android and iOS obfuscators won’t normally have an impact on Flutter Dart code obfuscation and vice versa.
Secure storage provides a way to securely store small amounts of key / value information on the device.
Here are some other unrelated requirements that are important by themselves, but don’t fit neatly into any of the above categories.
Error / Crash reporting: Sentry library.
Third party / open source libraries: List third party libraries and licences. Usage of third party libraries often require the app to publicly acknowledge library usage and provide a way to view those library licences.
Generate and scan QR codes.
Access to personal contacts list.
Share details with social media.
Receive payments via an attached card reader using the Square Reader SDK.
Make in-app payments using the Square In-App payments SDK.
Read user’s health information.
Who else is using Flutter?
Stadia, Google’s upcoming cloud gaming service, selected Flutter for its Android and iOS app implementations. See here and here for other high profile companies and apps that have chosen to use Flutter.
As can be seen from the links provided above, there is a Flutter library or solution available for the many and diverse requirements applicable to Enterprise mobile apps.
With a healthy and growing Flutter library package ecosystem, maybe it’s time to consider Flutter for implementing your next Enterprise mobile app!