iOS app development: Calling and dismissing FlutterViewController in native applications
Wondering how to manage the Flutter framework from a native iOS app, and, more specifically, how to call and dismiss FlutterViewController? Let’s see how it works!
What is Flutter?
We have already published a series of articles about the Flutter development framework.
In short, Flutter is a mobile development framework released by Google in 2017, based on the Dart programming language. Google's OS Fuchsia, as well as Alibaba and New York Times are among Flutter's adopters. The framework, understood as a set of reusable libraries containing ready solutions to common programming problems, is planning to go multiplatform in the future.
But 'a framework' can be understood a bit differently when talking about specific mobile development projects.
Flutter as an iOS framework
If you work with iOS, you probably know the other meaning of the word 'framework', as well as when to use it.
A framework is a piece of code or even a working project that can be injected into another app's source code.
The most popular way to use it is CocoaPods. Frameworks can be also generated locally. Many developers do it for their own purposes.
But frameworks can be built not only with Xcode.
A relatively new way to do this is... Flutter. It has another advantage: Flutter's modules can also be used (for example as AAR) in Android projects.
The idea is quite good and this is why I wanted to use it for my next iOS framework.
How do you call native code in Flutter?
After building and testing my Flutter framework for an iOS project, I faced first the challenge - how to call and dismiss a framework?
You should know that I wanted to use it as a separate module, launched and closed, inside my app.
Calling a framework is quite easy and well described in official tutorial.
What you need to do is to call FlutterEngine
and the present view. If you want to manipulate your Flutter framework - just like a regular UIViewController
- you need to call FlutterViewController
.
Just like this:
let controller = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)
Then you can call for example:
controller.dismiss(animated: true, completion: nil)
That’s quite easy, but let’s assume that the user needs to push some button from Flutter side to dismiss a module.
But how should a native iOS app know that a Flutter button is pressed? This is where we need to use FlutterMethodCallHandler
. This method is quite thoroughly described in Google's Flutter tutorials, so there is no need to repeat it here.
You should just know that on the Flutter side you need to add a method channel that can be listened from a native app. On the Swift side, implement a channel:
let channel = FlutterMethodChannel(name: "com.prograils.myApp/didCloseView", binaryMessenger: controller.binaryMessenger)
channel.setMethodCallHandler { (methodCall, result) in
switch methodCall.method {
case "didCloseView":
controller.dismiss(animated: true, completion: nil)
default:
debugPrint(methodCall.method)
result(methodCall.method)
}
}
By using the Method Channel from Flutter you can get many events and actions from the Flutter framework. In this case, I used it only to close the FlutterViewController
. But the Methods Channel can also be used for sending objects and even streaming.
For now - that’s all. Thanks for reading!