I have been working in the Native Android app development for more than 5 years. As stated in previous blog, as a team we wanted to explore the Hybrid app development platform. The idea behind opting for hybrid application development was adding the skill set that helps fast app development with single code base. As mentioned in previous blog, after digging into a lot of options and comparison between various hybrid technologies we finally opted for Flutter framework.
As we set out to try our hand’s on app development with the Flutter, we thought of developing a simple HRMS application which will have Odoo CRM as its backend. The idea behind this application was to get the experience of Hybrid technology and more specifically Flutter framework to develop a simple interactive application for employees of an organization to manage their leaves and timesheet records.
In this blog I will be sharing my experience of developing this HRMS app using Flutter framework.
Following are the steps involved in this entire app development:
Step 1- Setting Up:
- To install the Flutter SDK for iOS or Android app development the basic development setup was required e.g. Android SDK, Xcode, Java JDK etc.
- As the Flutter is open source SDK, just with the minimal requirement it was quite easy to install Flutter SDK on both Windows and Mac system. Further, Flutter document has given a detail description of how to install the SDK to respective systems.
- Even if Flutter supports many IDE for app development, we choose VS Code by just installing additional Dart and Flutter plugin.
Step 2- Development:
This was done on trial basis to check capabilities and support by Flutter. But to our surprise everything that can be developed in Native was possible in Flutter. So, starting with the UI designing we came across many more designing features of Flutter.
Everything in Flutter is “Widget”. I believe that it can be a bit challenging for Native developer to understand that every UI component that we use in Flutter is a Widget and no separate XML or Storyborad or xib is available for its implementation. Even a TextView in Android XML is a Text Widget in Flutter. The entire app Designing moves around the Widgets and undoubtedly flutter has given a huge set of Widgets for App development.
The following screenshots can show how similar the app can look on both the platforms.
The challenge the Native interface for respective platforms. To accomplish this task Flutter has given 2 separate libraries named material design for Android and Cupertino for iOS. Both these Libraries has rich set of widgets which we have used for providing native experience to respective platforms.
Also, for maintaining same UI theme throughout the app in terms of Font and colors for Widgets the ThemeData class is used.
Flutter has provided state class which helps developer to make the UI interactive. SetState method of stateclass is used to change the UI component at run time depending on the user’s actions.
Setstate method calls the build method, which as a result builds the entire screen to reflect the changes.
State management tools are provided by flutter which helps to maintain the state of the data throughout the widget trees. Flutter has provided many options like Bloc, Provider etc. I chose Provider as it is popular among the developers and recommended by Flutter itself.
In Android Native the state of the data can be managed using “SavedInstanceState” methods whereas Flutter uses different mechanism.
Understating the State management in flutter was quite hard initially because the app is build using the different widgets and the state management works throughout this widget tree.
- API Integration and Web calls:
Implementing APIs was the major task in this app as employees can apply the leaves and daily timesheets and can also view the status of the same. To accomplish this, the http package is provided by flutter for implementing web calls. This package provides its own methods for GET and POST API calls which simplifies the implementation.
Flutter has also provided async method to execute asynchronous tasks effectively with minimum code and returns a result as Future class object for further use. The Json response from API calls can be handled easily as it provides methods to encode and decode json response and store it as dart object.
In every app there are some data values that need to be stored locally so as to use them throughout the lifecycle of the app. Flutter has provided sharedpreferences plugin which is used to store data in key-value pair. Some API response values were stored in SharedPreferences for handling the conditions based on that value. E.g. employee location was stored in shared preference to change the user interface according to the location. Data from API that was not to be change frequently hence was stored in local database using Sqflite package. Both these approaches were quite same that I use in Native Android app and so it was easy to implement.
As app provide interface for both employees and Manger, we wanted to provide push notification feature through which the approval request can be notified to Manager and a response of the request can be notified to employee. We implemented Push notification feature easily with Firebase push notification service. This required some Native configuration to be done at both platforms.
As Flutter provides 2 different sets of widgets for different Platform it was important to differentiate the code based on which platform it is running on. This was easily detected with built–in methods.
e.g. If the app requires special run time permissions for Android app then the code can be separated by adding if (Platform.Android). This will detect the platform and execute the intended code at run time.
Following Screenshot shows that the widget specific to platform is added at runtime depending on which platform it is running
The Date picker for both platforms are different and separate widgets are provided for it.
- Easy Native code Implementation:
Even if Flutter provides all the native feature for its developer there are some platform specific codes that need to be written in Native language. For such feature we have added Native code to Kotlin and swift files.
This key feature is a time saving thing for developer which works as charm. Instead of waiting for app to run after changing just a line of code, Flutter has provided Hot reload functionality which allows to “Make a change and reload app and see the changes in fraction of seconds”.
Flutter has provided a large set of packages and libraries as well as the community contributors adding a lot more to it every day.
Step 3- App Publishing:
After the development of full fledge app, the last thing is app distribution. Even if Flutter is single code base, the app publishing needs to be done differently. Flutter has provided detailed documentation on both Android and iOS app upload.
- Android App: The version code and version name can be set in pubspec.yaml file which is in format versionName + versionCode e.g. 1.0.0+1. The Android app apk can be created through traditional way using Android Studio but We created the keystore file (.jks) and apk/bundle through Flutter commands from terminal. Keystore is basically a digital signature to verify the authenticity of the upload and apk is an Android package. After creating the apk/bundle the app was uploaded to Google Play store.
- iOS App: Flutter has provided Android and iOS bundle separately so iOS app can be accessed through Xcode. We made some basic configuration changes related app version and certificates and created archive of the app. On App store we created app version which is just like what we configured in XCode project e.g. 1.0.0. Once the archive is ready, we uploaded app to App Store connect.
No special changes were required for both iOS and Android app publishing and even the app release was not affected by hybrid platform.
- As a Native Android developer, I have a habit to design the XML file for user interface and check the UI preview even prior to running the app to see how my screen will look like. Flutter lacks in this functionality as no separate UI file can be built with it. The changes made in the UI can be seen only after we run the app in the device. But once we run the app and start changing the UI, the changes get reflected in the current instance of the app with host reload.
- Even if Flutter has rich set of Widget, building the customized UI is bit difficult with existing widgets.
- The basic app size with flutter is quite large when compared to Native application for both Android and iOS platform. No doubt Google will come up with some features to reduce the app size very soon.
- To implement some functionalities like Silent push notification, developer has to do setup at Native side and handle the entire functionality from both Native and Flutter end.
Even if I am a Native Android developer, it was not much of a challenge developing a Hybrid app with Flutter Framework. Potentially, it resulted in saving a great amount of time and effort when compared to Native app development. Also, maintaining a single code for both platforms save developer from hassle of maintaining two different projects.
Certainly, if you are looking to develop an app which works across platform we suggest to use Flutter don’t forgot to reach team CENTELON to make the project successful!!