Mobile operating systems, such as Android and iOS, are meticulously crafted using their designated programming languages—Java for Android and Objective-C/Swift for iOS.
Applications developed in these native languages enjoy seamless access to all operating system APIs, ensuring direct and efficient communication.
This stands in contrast to various cross-platform frameworks that necessitate a bridging mechanism.
While cross-platform tools like Flutter excel in constructing functional and valuable apps, they do have inherent limitations.
Nevertheless, Flutter distinguishes itself by providing support for both writing and calling native APIs.
This capability empowers developers to harness the complete potential of the underlying operating system, thereby offering a more integrated and powerful flutter app development experience.
In this article, we will talk about Languages you can write custom native code and APIs in Flutter.
Languages supported by Flutter
Dart
Dart serves as the foundational technology for Flutter, a versatile framework for crafting web, desktop, and mobile applications.
Developed by Lars Bak and Kasper Lund at Google, Dart is a client-centric, object-oriented programming language introduced in 2011.
Dart was intended to run its own VM on the browser and to compete against JavaScript’s flexibility on the web or better yet, replace JavaScript but these plans were later dropped in 2015 with Dart 1.9 release and the focus shifted to compiling Dart to JavaScript instead.
Dart was able to run on all major browsers thanks to source-to-source transpilers.
The Dart team built different transpilers to convert Dart code JavaScript that runs better than handwritten JavaScript code.
Some of these compilers were:
- dartc
- frog
- Dart2js
- dartdevc
Dartc and Frog were deprecated because they were unstable and had performance limitations.
However, dart2js and dartdevc evolved better than other compilers/transpilers.
The dart2js is called when developers need to build development apps and dartdevc is called during development.
Dart for Flutter
The Flutter team could have picked any other language like Kotlin which had Google’s support was also built for cross-platform development and was Java-independent.
So it would have been writing native code that works on all platforms but somehow, Dart was chosen which makes people curious.
According to the Flutter team, Dart first met most of their value propositions like developer productivity, object orientation, predictability, high performance, and fast allocation.
These criteria were efficiently met by Dart and in addition, the Dart team is investing a lot to keep making Dart better.
It is important to note that Dart’s runtimes and compilers supported just-in-time (JIT) compilation, contributing to Flutter’s killer hot reload feature.
Additionally, the Ahead of Time compilation (AOT) capability emits ARM code, which enhances start-up speed, predictability, and overall performance, two key elements that contribute to Flutter’s appeal.
Dart for custom-specific code
Dart’s type safety, makes it convenient to receive data from and to the platform-specific target through serialization.
To write platform-specific methods, Flutter uses the MethodChannel mechanism written in their native code for each specific platform.
This allows Flutter to communicate with native APIs seamlessly.
Note: Dart and Flutter do not rely on these native APIs to create a functional app.
They only implement native-specific code when there is a need.
Custom Native code in Flutter
Platform Channels
The platform channel is like a bridge that allows for communication between the native side of the platform being executed and the Flutter side.
The Flutter side sends a request and the current platform listens to this request; it is like an API call but this time not to a server.
The seamless communication between these two sides is possible through serialization.
The standard platform channel uses a standard message codec that supports binary serialization of simple JSON values like Strings, byte values, boolean, etc.
Flutter exposes a class called MethodChannel which allows both ends to invoke methods.
Dart calls a native method on the channel and the native code implements a handler for that method.
Some Flutter use cases are usually used when you need to access features like the camera, battery level, GPS, or other sensors.
Implementation steps
- Define or construct a channel using the MethodChannel that connects both sides (Dart and native side).
- Invoke a concrete method to be called from the native API by using a String identifier. These methods are usually asynchronous.
- Serialize and deserialize appropriately; although this is handled automatically by the Method channel.
Flutter support for Kotlin
Kotlin is a multi-platform language.
This language aims at sharing code across different platforms to cut down time to create functional apps while not sacrificing native performance.
Kotlin is completely independent and has its own API that calls native functions. Kotlin was meant to be the improvement of Java’s shortcomings and it has however lived up to its expectations.
However, it is made to be completely interoperable with Java.
You can run Kotlin on a Java Virtual machine (JVM) which allows for integrating with existing Java libraries.
Kotlin native and Flutter
Kotlin native is a self-contained technology in the Kotlin ecosystem that allows Kotlin to compile Kotlin code to binaries.
While you let Flutter handle and render the UI using SKIA a 2D rendering engine, you can use Kotlin to write platform logic, allowing Flutter to communicate with Kotlin native components.
You can check out the post for more on Kotlin and Flutter.
Flutter support for C++
C++ is an object-oriented language used to build a Windows UI.
Windows low-level functionalities and drivers are all written in C while the higher functions that include the UI are written in C++.
C++ exposes things like classes, polymorphism, and inheritances which help developers build amazing user interfaces with frameworks like Microsoft Foundation Classes( MFC) and WinAPI.
With Flutter’s support for Windows and Linux, developers can build their intuitive and stunning UI with Flutter’s customizable widgets, bringing a whole new look and feel to the Windows and Linux ecosystem.
C++ and Flutter
C++ and Flutter put together is an open door to accessing more powerful libraries.
This will enable seamless connection to the low-level Windows and Linux services.
With the platform channel, Flutter can integrate with existing C++ libraries to power your Flutter app.
If you are developing a game with Flutter for Windows, you can access some game logic and rendering modes written in C/C++.
Flutter support for Swift/Objective-C
Swift is the new and improved language introduced by Apple to replace Objective-C.
However, it was made to be interoperable with Objective-C. This means you can integrate existing Objective-C systems with Swift.
Swift is an object-oriented and expressive language that is aimed at building for multi-platform in the Apple ecosystem.
Swift’s core features were safety and performance through better memory management using Automatic memory counting (AMC).
See our article to learn more about Swift.
Swift and Flutter
Swift is the primary development language for iOS apps so if you need direct access to the Swift libraries and native UI components, you can access them using the platform channel.
Swift is known for its performance, so if you need to optimize your Flutter app, you can implement Swift’s optimization modules to improve your app.
Note: This is not only specific to Swift but also Objective-C.
You can also access Objective-C APIs through the MethodChannel.
Conclusion
We have highlighted Flutter’s all the languages that Flutter apps can leverage for native services.
While native languages are tailored for specific platforms, Flutter showcases its versatility and adaptability.
Dart as the choice for foundational language is discussed highlighting its evolution, and support for JIT and AOT.
This choice seems to be optimal and works as intended.
It is also important to note that some platform-specific functions are already packages.
So you do not have to directly access the MethodChannel yourself.