EntrenaPro — From Zero To Flutter
Published 40+ Screens App in 4 Months built with Flutter + ❤️
Purpose of this post is to share my journey and inspire other tech companies to choose Flutter for their next project.
It begins when Peri, the Product Owner who had worked with me before asked if there was any possibility if re-doing all the mockups for EntrenaPro iOS and Android app in less than 4 months. He shared invision link for the project. He was open to choose any cross-platform framework that can help us to deliver in a very tight deadline. EntrenaPro is an app where Coaches and Athletes can schedule individual and public sports sessions between more than 40 activities all over Spain.
My Introduction With Flutter
In 2015 I saw above video that time I liked the idea but I never got the opportunity to try it. Until project came in with a very tight deadline and an app was needed to build for both platforms. And I was free to pick any framework, so I chose Flutter. Since 2015 Flutter has come a long way.
Why I Choose Flutter, Not React Native
When I had to decide at that time I had no experience with Flutter and one week of experience with React-Native (I started an app on my own that I never finished). These were the points in decision making:
- Speed of delivery, Developer productivity. I had read about it on multiple places
- When Flutter paints the screen it uses its own surface and draws Widgets (Views, Buttons, Texts) on that surface, so Flutter has control of each and every pixel on the screen. Flutter doesn’t use OEM widgets. On the other hand, React Native uses OEM widgets to draw Components on the screen. It means when you draw a widget using Flutter, it will look 100% the same on each platform, no matter if the platform OEM widget has support for it or not. And Flutter also has platform aware widgets and platform aware physics
- I am biased towards Google products
I don’t want to give an impression that RN is bad, no doubt many successful apps have been developed in RN and they look GREAT. But my first 6 days encounter was not pleasant (try to create a view with shadow properties x = 0, y = 2, blur = 6, spread = 0 and test it on both platforms), so I tried something new. Flutter and React Native offers Cross-Platform development differently and I personally like the Flutter approach more.
My Journey With Flutter
The installation process was easy for me. I assume as Android developer you already have the Android Studio in your system
1. Clone the Flutter repo
2. Setup environment variables
3. Run `flutter doctor` command
4. Install flutter plugin in Android Studio
Here is the more detailed official guide https://flutter.io/get-started/install/
I never faced the trouble during the installation but I have seen other people facing issue during installation process and Flutter community is very helpful in this regard.
Picking Up Dart and Flutter
I was coming from Java and I started to write basic Dart on the first day, the syntax was very similar and in later days my grammar started to improve and it is still improving. Dart has built-in support for Streams and Futures. My RxJava knowledge helped me with streams and ES6 Promise knowledge helped me with Futures, Async/Await. I was productive from day one. I feel people coming from Strongly Typed languages will pick it up early but people coming from dynamic languages will face little hard time.
In Flutter everything is Widget. This was a different thing for me, but documentation and tutorials helped me a lot in getting started. My first two-three days were very confused because there were a lot of new concepts, lay outing, styling, padding everything was a Widget. And after mapping concept from Android UI system to Flutter UI system things started to get easier. I started to feel more confident. And I very much like the Declarative way of UI.
Above all Flutter Hot Reload and Hot Restart features were reducing the testing time, every UI change takes only 0.7 (mostly) ~2 (sometimes) seconds at max to appear on the screen in my project. Plus Flutter also maintains the state of the Widget. If you have entered the text and selected the checkboxes and now you are changing the checkbox color it will change the color only and will keep them selected. It helps me to show more productivity. If I calculate then I think it could save more than 40% of the time w.r.t. testing in native development.
Like any other good programming language Dart also have package management solution. https://pub.dartlang.org/ They call it Pub. Dart officially supports it. It is very similar to NPM.
First Week, First Screens, Adaptability, Reusability
In my first week, I completed Login and Registration screen and result was phenomenal. Adaptability was great, when I sent the device screenshots to the designer he said, “Wao, very balanced”
Flutter uses Declarative way of UI, it increases the widget reusability a lot, and I created a “Bonus” widget and used it on multiple places, same for “User Avatar”. Extracting anything into a widget is easy and the widget can be reused anywhere.
Challenges I Enjoy
In Flutter you not face the challenges but you enjoy them.
For example, according to a design of a screen I need a month picker and there was no readily available package for that to use, PageView widget was closely resembling to the UI, I dig into the code I understand it and I created my own Widget and published it to the Pub.
month_picker_strip Flutter and Dart package - A library that helps user to pick a monthpub.dartlang.org
And on another screen, I needed a range slider but there was only Slider available with a Single thumb, I dig into the Cupertino Slider code and created a new Range Slider Widget and published it to Pub.
cupertino_range_slider Flutter and Dart package - Widget is a slider that help you to choose a range from a set of…pub.dartlang.org
It was a challenge because there was no official support in Dart. There were few packages available in Pub but we needed more detailed integration. I decided to write Plugin (A specialized Dart package which contained an API written in Dart code combined with a platform-specific implementation for Android using Java or Kotlin, and/or for iOS using ObjC or Swift) for that. But when I checked official SDK of stripe for iOS and Android on github I found their code was not similar in terms of the function signature. In Android SDK theirs one function returns the result but counterpart iOS SDK returns nothing. So I skip this idea and moved to the next one, which was write a package by reading their documentation and I followed documentation and Android SDK as a reference and completed set of features required by the App.
I used Firebase Cloud Messing for both iOS and Android. Flutter had an official plugin for that, First I used that plugin to integrate Push notification. But later requirements changed and we had to make real-time updates on screen content based on the data in the notification. That was the point where I had to include platform channels in project. I removed the official plugin from the project and started to write my own Firebase integration code for android(Java) and iOS (Swift). Using platform channels I also started to push the data on Dart side whenever I received notification on the platform side. It also enabled me to open specific screen based on notification type when user taps on the notification.
On a large project structuring the code plays a very important role, when I started the project popular options were: 1. Redux, 2. Scoped Model. I started to follow Redux, I personally don’t like redux, putting everything in one store is not my taste, but luckily in Google IO 2018 they give a talk about this topic and I started to convert architecture to BLOC pattern. It is fulfilling every purpose and still I am learning the best practices in BLOC pattern
We were near the deadline and Product Owner thought we needed to add one more Developer so he can work on translations in parallel. I did a mistake (or I was a beginner) during the development I did not extract out the Strings in app localization file, so other developer took the responsibility and extracted out the string and completed the translations file, It took him one week to complete the translations
Later product owner asked me to change some of the translations in the app, to make it more meaningful and then I realized how hard to work with translations in Flutter as compared to Android. We used Dart intl tools for generating .arb file and then back .dart file.
Creating Builds and Publishing
Creating builds are easy, documentation helps a lot when you have to create a release build. If you feel comfortable while creating builds on Xcode and Android you will feel yourself at home. There are just a few extra commands that generate dart executable code, and then for Xcode we follow normal procedure Build/Archive/Upload to Store. For Android, after setting keystroke simple one command creates a release build.
App Store just took one day to approve and listed on their store and App is available to download on both stores.
Si quieres practicar tu deporte favorito cerca de casa o del trabajo con los mejores profesionales, y confirmar…itunes.apple.com
EntrenaPRO es una aplicación para entrenar con los profesionales y centros deportivos de tu ciudad, al mejor precio y…play.google.com
What’s Next For Me
Nowadays I am focusing on Animations/Hero Animation and Custom widgets. I have to dig deeper into the in-code documentation and have to learn advance stuff. Isolates are next topic for me, where we have to perform some heavy lifting task on background threads. Schedule was very tight and we focused on finishing the app the soonest possible, so we didn’t focus on the test cases. Next thing is to be well versed with test cases in Flutter. In the end, I also have to learn Continuous Integration/Continuous Delivery.
I found Flutter is the best candidate for business apps. It helped me to complete the first version of the app in a very tight deadline. As a developer it gives me satisfaction that if UI is looking beautiful on iOS then it will look the same on Android. If you have to access something platform specific then there is a mechanism to do that, and it is easy. Dart language is easy to pick. Flutter HotReload saves a lot of time and increases productivity. Community is growing. Plus better tooling and IDE support.
About me: I’m an Android & Flutter developer, juggling between contract work, open source and side projects. That’s all, thanks! If you liked this post, don’t forget to leave a 👏!
App Features Overview
After reading a long post if you still interested what set of features an App built using Flutter could offer, here is the detail, EntreaPro App offers the following features set so far:
- Two very different roles (Athletes and Coaches) with different options, payments, side menus, and features.
- Geolocated searches for Coaches and Athletes(using Place Suggest API ).
- General view for scheduled sports sessions categorised by pending, accepted and cancelled.
- Stripe Connect integration (using webview to handle redirection response) to let every Athlete pay sessions to coach by Credit Card.
- Stripe integration (using custom api built in Dart)to let Coach pays a subscription to EntrenaPro.
- Sports bonus sold by Coaches where a number of tickets ready to be ticked after any session.
- Real-time updates and notifications (using Firebase Push Notification) for new Session Requests, Acceptance, Cancellations, Payments…
- Calendar picking to filter available time for any professional.
- Rating system with 5-stars, comments and replies
- Coach notebook to let him keep track of his offered sessions vs athlete performance
- Coach profile sharing (using firebase dynamic links)