Flutter make us focus on what matters most
I’m one of the founder of Tanibox, along with Asep and his wife. As a board member, my role is generally to give advice and direction. In one point of time we pivoted our business model and in need of creating an app that works on Android and iOS. I became a little bit involved when we tried to figure out how to do this.
At first we thought that we just create native app separately for each platform. As we needed to test ideas quickly we search for vendor. But after 2 weeks it didn’t work out. The iteration was too slow for us and we learnt that we really need to build this in-house. The only viable option was React Native. But we disliked the idea of regressing to Javascript.
Flutter is our life saver
I and Asep has written a number of native iOS and Android applications in the past. We agreed that the most expensive investment is in the UI and the interaction as it usually changes quickly so we want to optimise on this part. We finally hired a seasoned mobile engineer to write our app and challenge him to explore Flutter. This has been working relatively well. This is what we’ve been learning until now:
An agile way of writing UI
The problem with writing app in two platforms in their own respective UI framework was the time, money, and expertise needed to craft the UI. Every platform has its own behaviours and every company has its own branding and UI guidelines which may or may not inline with the guidelines set forward by platform owner. It also takes most of development time. We’re just a little startup and we want to test our product FAST.
Flutter framework is written on top of Flutter Engine. The engine takes care of abstraction of renderer for three platforms: Android, iOS, and Fuchsia. The framework is focused on UI widget rendering. It implements its own rendering stack based on Skia. It does not use iOS UIView
or Android’s View
class.
Game engines have been doing this for very long time. Every game engine has their UI rendering library which enables game developer to compose UI with their own branding, style and interaction on all platforms. Games do not even adhere the “UI Guidelines” because they need to stand out.
Applications nowadays tend to design around the brand and not the platform. If people already familiar with the app in one platform, they expect they behave the same in another platform. Brand consistency is important. This is what we want to aim.
Flutter also handles its own animation and gestures. This gives Flutter total freedom on how UI widgets are composed and how user interact with them in similar fashion. Flutter enables us to write our UI based on our brand. The way Flutter was made is a match for our requirements.
It turns out we spent helluva lot of time building and tweaking the UI before even integrating to the backend. There’s always that “something” that needed to be adjusted fast. Flutter supports hot reload during debug build. Which mean developers can just adjust and run and see the result. This make us able to iterate the UI for both platform really quick. On release mode, flutter will spit out the AOT compiled code.
Consistent Way of Communicationg With The Backend
Our backend was written in Go and it exposes RESTful API. To make work effective, we created the SDK to make access to the server endpoints seamless. If we were to implement those in Android and iOS separately, we need to create two different libraries as they do HTTP and JSON marshalling and unmarshalling differently.
Thanks to Dart’s HTTP package, built_value, and built_collection, we’re able to write an asynchronous client SDK with immutable data structure. This SDK is used by both Android and iOS app and also WebApp because later on we decided to write our dashboard using Angular Dart to be able to further leverage our shared Dart SDK.
Just recently, the dart team even announced gRPC support for Dart. This is amazing as this will enable better integration as we’re planning to use gRPC on our services in the near future.
A Strongly Typed Language
We have strong opinion on using static typed language whenever possible. We like to express something in the term of type. This is the reason we decided not to use React Native in the first place.
Dart is not perfect, but it has things that we need: a statically typed language with combination of compile time type checking and runtime time type checking. It has built-in mechanism for asynchronous using future and async-await
. It helps tremendously on handling event and network packet.
Dart is similar to Java. Our API SDK for Dart is written by our backend engineer. We don’t really separate engineers by layers, and having language like Dart make our backend engineer can create one SDK for all three platforms in pure dart. The language is easy to grasp and it saved us tremendous amount of time.
But Flutter Also Make Us Suffer
While Flutter saved our investment in time and money. It was also a risk. This tweet showed my frustration when helping the team working on Amazon Cognito.
Possible Bug in Dart Standard Library
Edit: This is already Fixed.
We didn’t use stable channel at that time because the changes from dart 1 to dart 2 is major and we do need features from Dart 2. There was one particular bug that bugged me so much is the modpow(x^y mod N
) bug on dart dev channel before version 0.54. Amazon Cognito is utilising SRP and RSA for authenticating and verifiying token and I need BigInt
with correct modpow
implementation. I scavenged code from other people. Thankfully, Google have dart code handling simple rsa. I looked at them and learnt that my code was correct, but Dart implementation was buggy.
Documentation Scarcity
Edit: This is improving, but still lacks.
When I first used libraries create by Google itself likebuilt_value
and built_collections
, the docs was nearly zilch. In many occassion I need to peek in the source code on github to know what’s going on and how to use it. Thankfully, Google’s standard of publishing source code has plenty of examples on it.
Need To Build Things Yourself
At the time I wrote the app, there was no Amazon Cognito SDK for dart so I need to follow their documentation, test them out using rawcurl
, peek the source code written in other languages and reimplement it in dart.
We can’t rely on the availability of the libraries written for dart. Cognito is one example. For me this is fun part. But for other people, this can be a no-go. The amount of nights and coffee I spent to figure out how this things work in dart is paid off as once I can figure them up, it can be used on all three platforms with very minimal changes.
Conclusion
Working with bleeding edge technologies comes with risks but the risk of using Flutter and Dart is worth the investment. The fact that we used the dev channel just make us feel like we are working together with the Google’s Flutter and Dart team by always keeping track of the issues.
We managed to build our first prototype in 3 weeks with single client developer and single backend developer. This is impossible to do if we write them in their own respective IDE and language.
If you wonder what kind of app we’re making, Our CEO will announce it in coming months when our products is ready. So stay tuned.
Source: https://medium.com/@lynxluna/flutter-how-it-got-right-4865de34852
Written by
Tech Leadership, Software Craftsmanship, and Mastery is what I seek for. Good food and games distracts me along the way.