Written by Souvik Biswas
Most of the companies try to adopt a cross-platform app development framework so that they have to hire a small number of developers who would be handling both the iOS and native Android part. But, this mindset of people is slowly changing now, with the introduction of Flutter. Even some of the big companies (who already have developers for both native Android and iOS) are using Flutter in their production app. So, how is this drastic change coming? Let’s explore it in more detail.
What is Flutter
On the official Flutter Website, Flutter is defined as the Google’s UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase.
On December 4, 2018, Flutter 1.0 was released at the Flutter Live event, denoting the first “stable” version of the Framework. Since then Flutter has improved a lot in terms of performance.
Recently, on December 11, 2019, Flutter Interact took place and it brought a number of improvements to the Framework with the introduction of Flutter 1.12.
A summary of all the announcements in Flutter Interact is available here.
You can find some of the apps created using Flutter on their official Showcase webpage.
Overview of Flutter vs iOS
In the initial days of iOS development, the programming language used by Apple was Objective-C which most of the developers hated at that time but were forced to use as it was the only option available if you wanted to carry on with iOS development at that time. But fast-forward to 2014, Swift was introduced which was type-safe and used concise but expressive syntax, and developers just loved it. It was also fully compatible with Objective-C and the existing iOS APIs. Though the APIs that were used by Swift were not that good initially, they are a lot improved now.
Flutter was initially released keeping in mind these four pillars: Beautiful, Fast, Productive & Open. And after one year it has proven to hold onto it.
Most of the cross-platform app developments frameworks that are present, suffers from bad performance and stability issues. They are easily identifiable when they are run beside a native app. Flutter has bridged this performance gap to a large extent in comparison to other cross-platform frameworks, like React Native and Xamarin.
How did Flutter became as performant as a native app? The answer lies in its architecture and also the language used by Flutter, i.e., Dart.
As an iOS developer if you want to try out Flutter then there is a nice Official documentation available.
Architecture
Native Apps
In the native apps, whether it is Android or iOS, the native app code talks to the Platform to create OEM Widgets or for accessing various Services like audio, sensors, camera, etc. The widgets are rendered to a screen canvas, and events are passed back to the widgets. This architecture restricts the widgets to be reused across all platforms as they are OEM specific. And, this is the reason we have to write whole app for each platform separately.
Before moving on to Flutter, let’s checkout the architecture of another popular cross-platform solution, React Native.
React Native Apps
React Native apps are written in JavaScript, so to access the OEM widgets it has to use a bridge to talk to the Platform. This is where the bottleneck of this Framework lies.
So, the solution from React Native developers:
In order to architect performant React Native apps, we must keep passes over the bridge to a minimum.
Flutter Apps
Now, coming to the Flutter apps. Flutter solves the most challenging part of the other cross-platform frameworks, i.e. getting rid of the BRIDGE. Flutter does not use the OEM widgets, it provides its own widgets. Flutter moves the widgets and the renderer from the Platform into the app, which allows them to be customizable and extensible. This also helps Flutter to maintain the consistent 60 FPS.
Dart
Another reason that developers love Flutter is because of the Dart Language.
Dart is an object-oriented, class defined, garbage-collected language using a C-style syntax that trans-compiles optionally into JavaScript.
Though Swift is also a very good and modern language, but Dart has some features that separate it from the other languages:
Dart uses AOT (Ahead Of Time) compilation, which gives the fast startup and fully customizable Flutter widgets.
Dart also uses JIT (Just In Time) compilation, which is the main reason that Hot Reload exists. I will talk about it in a bit.
Dart has a garbage collector built in the language. This enables Flutter to achieve smooth animations and transitions that run at 60fps.
Dart allows Flutter to avoid the need of a separate declarative layout language or visual interface builders, like Storyboard in iOS, because Dart’s declarative, programmatic layout is easy to read and visualize.
Dart has a easy learning curve, because it has similarity with various other languages. It is the combination of the features of these languages that makes Dart so powerful.
At Flutter Interact, Dart was updated to version 2.7 with support for extension methods, character package and null safety preview. You can get more info from this article.
Hot Reload
In the native iOS app development, if we even make very simple changes like changing the color of a component, it will take at least 10 seconds to display the change onto screen.
Flutter’s Hot Reload allows the developers to only send the incremental changes of the source code to the running Dart VM, rather than running the whole code after each change. This enables it to make changes almost instant, and that also retaining the state of the app.
Flutter’s hot reload feature helps you quickly and easily experiment, build UIs, add features, and fix bugs.
If you haven’t yet tried out Flutter, just check it out once, at least in the name of Hot Reload. You have to see it to believe it.
Declarative UI code
Every component in Flutter is known as a Widget. The Flutter apps are created by combining these widgets (like building blocks) to form a widget tree. Even the final app we get is also a widget.
Flutter uses declarative UI.
In declarative style of programming, we are most concerned with what we want as the answer. Here, we as developers are not concerned with how we get there, simply concerned with the answer that is received.
That means Flutter uses UI as a function of state.
This also allows the Dart code to run on a single isolate.
Whereas, iOS development using Swift follows imperative programming paradigm.
In imperative style of programming, we care about how we get to an answer, step by step. We want the same result ultimately, but we are telling the complier to do things a certain way in order to achieve that correct answer we are looking for.
This also means Swift code runs across several threads and to maintain the communication between the components in iOS we have to use closures (callbacks), delegates, notifications, target-selectors, key-value observation, etc.
Swift uses a separate interface builder called Storyboard to design the UI of the app.
This often makes the code a lot complex to understand and reduces productivity.
As Flutter uses declarative code, it is lot cleaner and easier to refactor than the imperative style Swift code. Also, declarative code means that we are reasoning at a much higher level of abstraction as compared to imperative code.
Design Guidelines
Following iOS design guidelines in Flutter is really very easy. Flutter has a separate UI component library known as Cupertino Widgets. This contains all the widgets which follow iOS design guidelines by default.
With the introduction of Flutter 1.12, now there is no need to download each font from the Google Fonts library to use it in your Flutter app. You just have to include one package, google_fonts, and you will get access to the entire Google Fonts library.
Flutter 1.12 improved some of the Cupertino widgets and added complete dark mode support to them.
You can find the official iOS UI design tips here.
There is also a Google Codelab available for Building a Cupertino app with Flutter.
Dependency Management
iOS depends on some third-party tools for its dependency management system, like CocoaPods or Carthage. So, the iOS developers need to learn about these third-party dependency management tools.
Flutter uses its own dependency management system called Pub. The Pub Package manager is inbuilt with Flutter and it is easy to import new dependencies as needed for the app development.
You can get more info about how to use packages in Flutter here.
Add-to-app
Flutter can also be integrated to your existing iOS apps as a library or module. That module can then be imported into your iOS app to render a part of your app’s UI in Flutter.
As of Flutter 1.12, add-to-app is supported for the basic scenario of integrating one full-screen Flutter instance at a time per app.
A documentation for adding Flutter to an existing app is available here.
Testing
Apple uses XCTest as the testing framework starting with Xcode 5. The types of test that you can perform using XCTest are:
- Unit Tests
- Performance Tests
- UI Tests
XCTest is integrated tightly with the development environment of Xcode, so it provides easy-to-use and seamless workflow with other components and features of the development environment. But it has some performance and stability issues while running UI Tests on device.
Swift also lacks a proper mocking framework. So for mock testing, some of the frameworks that iOS developers rely on are Cuckoo & MockFive.
You can find a brief testing documentation for iOS here.
On the other hand, Flutter is very strong in terms of testing. It also has three catagories of testing:
- Unit Tests
- Integration Tests
- Widget Tests
The Widget test in Flutter is similar to component test or UI test of other frameworks. But Flutter runs widget tests as fast as unit tests, which gives it a huge advantage over the normal UI tests used in iOS. You can also use other testing frameworks like Mockito by using the mockito package in Flutter. For running Integration tests in Flutter, you have to include a package known as flutter_driver.
Documentation for testing Flutter apps is available here.
CI/CD
Continuous Integration (CI) and continuous delivery (CD) help developers to make code changes reliably and fast, and enables them to deliver their app on time. Both Flutter and iOS have a great CI/CD support available.
There are various cloud-based CI/CD services available for use with iOS projects, like Nevercode, BuddyBuild, Jenkins, Travis CI, CircleCI, Bitrise.
These cloud-based CI/CD services handles all the iOS build process including testing, code signing and deploying apps to specific services or iTunes connects. We can also write our own custom scripts to achieve specific needs.
Codemagic was introduced as the first and dedicated CI/CD solution only for Flutter. But now it also has support for non-Flutter apps using codemagic.yaml. This makes it capable of building, testing and delivering native apps with Flutter modules added to it.
As of now
codemagic.yaml
has support for only Android and Web, but iOS support would be added very soon.
Can Flutter dominate over iOS?
Flutter is full of features and it promises a good performance, but it still not production ready for certain applications.
It lacks in availability of certain plugins. Some of the important plugins that are available, are still buggy and are not usable in large scale production application. But this highly depends on the kind of app you or your company would be working on, if you get good plugins and it satisfies your app’s feature needs, then Flutter might be the best choice for you.
As you might have already understood till now, Flutter takes a very different approach as compared to other cross-platform solutions, which enables it to achieve nearly native performance and the Dart language makes it really easy for developers to show their creative skills, by making the apps beautiful and intuitive to use for the users.
At this point in time, you shouldn’t ignore Flutter. If you haven’t yet tried out Flutter then go and try it now, because it is better late then never.
Some other strong points of Flutter that separates it from other frameworks are listed below.
Octoverse report
According to the GitHub’s OCTOVERSE report of 2019, Flutter is one of the fastest growing open source projects and it has climbed to the 2nd position.
Dart has become the fastest growing programming language on GitHub.
Fuchsia
Fuchsia is an open source operating system currently being developed by Google.
Flutter was developed in the early phases keeping Fuchsia in mind. Fuchsia uses Flutter as its UI rendering engine.
What makes Fuchsia so unique is the ability to run on any CPU architecture. It is based on their own micro-kernel called Zircon which they claim is able to run on smartphones, desktops, embedded systems and more.
There is an official Fuchsia webpage, which contains some documentation on how to get started with Fuchsia.
At this point of time, it is not known when the Fuchsia OS will be available and what kind of devices will it support.
RIVE
Rive (previously 2Dimensions) is a powerful design and animation tool, which allows designers and developers to easily integrate sophisticated animations into their platform. You can import Rive animations directly into your Flutter apps which run smoothly at 60 fps.
For more info check out their official website.
Ambient Computing
At Flutter Interact ‘19, Flutter was introduced as the UI platform designed for ambient computing. By this they meant to say that initially Flutter was introduced as the cross platform solution only for mobile devices, but now it is expanding to even web, macOS, embedded devices, etc. You can say that the Flutter framework is showing its true powers now, and I can’t wait to see what it can do in the future.
Community Support
As Flutter is totally an open source project, the developer community plays an important role in its success. There are a number of awesome Flutter plugins that came from this community and developers are experimenting with new things in Flutter every day, pushing it’s limits.
Conclusion
Flutter has become a really powerful framework and can’t be ignored anymore. Whether you love or hate Flutter, as an iOS Developer, you should definitely try out Flutter and Dart to understand their true powers.
Whether Flutter will replace native iOS, still remains a question. While we wait for this answer, it is safe to say that Flutter has a very bright future. Even if it fails to replace native app development, it has already proved to be the best UI design framework available at this point of time.
Souvik Biswas is a passionate Mobile App Developer (Android and Flutter). He has worked on a number of mobile apps throughout his journey. Loves open source contribution on GitHub. He is currently pursuing a B.Tech degree in Computer Science and Engineering from Indian Institute of Information Technology Kalyani. He also writes Flutter articles on Medium - Flutter Community.