Method Channel in Flutter: Bridge Native Code Example

We will learn how to use the method channel in Flutter to communicate data between Flutter and native code. In this article, Understanding how to pass arguments to the Android and iOS native platforms and return the value from native code to Flutter.

flutter method channel, method channel flutter, flutter platform channel, flutter method channel example, flutter method channel ios example, flutter method channel arguments, flutter method channel callback, flutter method channel tutorial, flutter ios methodchannel, flutter platform channel example, flutter android channel, flutter channel android, call iOS native code in Flutter

 

Flutter is a cross-platform framework. Sometimes you need to interact with platform-specific code (Android and iOS). At this point, a method channel flutter comes into the picture. The Flutter method channel provides a simple way to communicate dart code and your Kotlin/Java for Android or Swift/Objective-C for iOS. Here, we will see an example of multiplication of two numbers. We will pass two numbers as arguments from dart code. Multiplication logic is implemented in native code. The result will be returned to the Flutter code. We will see how to use method channels in Flutter with examples.

How to Use Method Channel in Flutter

To use Method Channel in Flutter, you need to define a channel with a specific name and setup communication between Flutter and the native platform. You have to write code on both sides. Once you create a channel on the dart side, then the same channel name has to be used on the native side. If you define the wrong channel name, then you can’t bridge between Flutter and the native platform. We will see a step-by-step guide with a code on both sides below:

Step 1: Setup Method Channel in Flutter

Create a method channel name in your dart file of the Flutter app. You need to import the services package of Flutter. Call a method named callMultiplyNumbers() on the ElevatedButton action. 

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Method Channel',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blueAccent),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Method Channel'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  
  static const MethodChannel _channel = const MethodChannel('method_channel_flutter');
   
  int result = 0;

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            Text("$result",style: const TextStyle(fontSize: 16)),
            ElevatedButton(
              onPressed: (){
                  callMultiplyNumbers();
              },
              child: const Text('Get Result'),
            ),

          ],
        ),
      ),
    );
  }
}
Step 2: Create invokeMethod in the dart file.

You need to create an invokeMethod to pass the specified arguments. You can pass int, string, bool, and more data types as arguments. Make sure that the name of the invoke method is the same in native code to get the arguments.

void callMultiplyNumbers() async {
    var returnValue = await _channel.invokeMethod("multiplynumbers", <String, dynamic>{
      'num1': 50,
      'num2': 10,
    });
    print("RESULT $returnValue");
    setState(() {
      result = returnValue["Multiply"];
    });
  }
Step 3: Android Native Code (Kotlin)

In your Android project, open the MainActivity.kt file from the android folder of the Flutter project. For accessing this file, you can find the path as Android > App > Main > Kotlin. Create a method channel name in the MainActivity class, same as you defined in Dart code. You can see the full code for the MainActivity.kt file below:

package com.example.flutter_method_channel

import io.flutter.embedding.android.FlutterActivity
import io.flutter.plugin.common.MethodChannel
import io.flutter.embedding.engine.FlutterEngine
import androidx.annotation.NonNull

class MainActivity: FlutterActivity(){
    private val SHARE_CHANNEL = "method_channel_flutter"


    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, SHARE_CHANNEL).setMethodCallHandler { call, result ->
            if (call.method.equals("multiplynumbers")) {

                val args = call.arguments as Map<String, Any>
                val a = args["num1"] as Int;
                val b = args["num2"] as Int;
                val multiply: Int = a * b;
                result(multiply)
            }else{
                result.notImplemented()
            }

            }
        }

}
flutter method channel, method channel flutter, flutter platform channel, flutter method channel example, flutter method channel ios example, flutter method channel arguments, flutter method channel callback, flutter method channel tutorial, flutter ios methodchannel, flutter platform channel example, flutter android channel, flutter channel android, call iOS native code in Flutter

Step 4: iOS Native Code (Swift)

In your iOS project, open the AppDelegate.swift file from the iOS folder of the Flutter project. For accessing this file, you can find the path as iOS > Runner > AppDelegate.swift. Create a method channel name in the AppDelegate class, same as you defined in Dart code. You can see the full code for the AppDelegate.swift file below:

import Flutter
import UIKit

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {

  let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
          let myChannnel = FlutterMethodChannel(
              name: "method_channel_flutter",
              binaryMessenger: controller.binaryMessenger)

          myChannnel.setMethodCallHandler({
              (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in

              if(call.method == "multiplynumbers"){
                  let c: Int = self.multiplyNumber(call: call) // function is written separately
                  let finalResult: [String: Int] = ["Multiply" : c]
                  result(finalResult)
              }else{
                  result(FlutterMethodNotImplemented)
              }
          })

    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

  func multiplyNumber(call: FlutterMethodCall) -> Int {
          let args = call.arguments as? Dictionary<String, Any>
          let a = args?["num1"] as! Int
          let b = args?["num2"] as! Int
          print(a as Int)
          print(b as Int)
          let c = a * b
          return c;
      }
}
call iOS native code in Flutter, flutter method channel ios example

Pros of Using the Flutter Method Channel

  • Access to Native Features: You can access native platform-specific APIs in your dart code that Flutter does not provide.
  • Custom Integration: You can use native libraries and features with full control from the Flutter project.
  • Cross-Platform Support: Method Channel works for both iOS and Android.
  • Sharing multiple files using native code: customized sharing dialogue using native code on each platform.

Cons of Using Platform Channel Flutter

  • Extra Development: You need to write platform-specific code for both. You need to be familiar with the syntax of the Swift and Kotlin languages and the implementation  code in each language for each platform, which adds complexity.
  • Maintenance: You need to maintain code on both Flutter and the native side.

Conclusion

Method Channels in Flutter provide a powerful way to communicate between Flutter and native code. It also enables platform-specific features. By following the examples in this article, you can setup a simple method channel, pass arguments, and handle callbacks. Whether you are working on Android or iOS, Method Channels make it easy to integrate native functionality into your Flutter app.

Frequently Asked Questions(FAQs)

How to call iOS native code in Flutter?

call iOS native code in Flutter, flutter method channel ios example

To call iOS native code in Flutter, you need to create a method channel in Flutter. You can communicate two ways from Flutter to the native platform. Create a channel name in the dart file, in which you can invoke Method by passing the arguments to iOS native code. You need to put some code in the AppDelegate.swift file. I explained the full code example in this article.

What are platform channels in Flutter?

Platform channels in Flutter are known as a two-way communication channel. It communicates data as arguments pass from Flutter to native platform code and callback results vice versa. You can use native code API features in your Flutter project. Using method channel in your Flutter project, you can bridge between Flutter and platform-specific code.

Leave a comment