Pigeon for Flutter: Type-Safe Platform Communication

Published on by Flutter News Hub

Pigeon for Flutter: Type-Safe Platform Communication

Pigeon is a Flutter tool that simplifies the process of communication between Flutter apps and their host platforms. It eliminates the need for manual string formatting and custom platform channel code, improving efficiency and type safety.

Supported Platforms and Data Types

Pigeon supports code generation for:

  • iOS and macOS: Kotlin and Java for Android, Swift and Objective-C for iOS and macOS
  • Windows: C++ for Windows

Pigeon supports all data types supported by platform channels, including custom classes, nested data types, and enums.

Features

  • Type Safety: Pigeon ensures that data types are consistent across the interface, preventing errors.
  • Code Generation: Pigeon eliminates the need for manual code writing, saving time and effort.
  • Synchronous and Asynchronous Methods: Handle both synchronous and asynchronous method calls.
  • Error Handling: Map exceptions to Flutter PlatformExceptions for seamless error management.
  • Task Queue Support: Optimize performance by using the Flutter TaskQueue API.
  • Multi-Instance Support: Create multiple instances of APIs with unique message channel suffixes.

Usage

To use Pigeon:

  1. Add Pigeon as a Dependency:
flutter pub add pigeon
  1. Define Communication Interface: Create a ".dart" file outside the "lib" directory to define the API interface.
// pigeon_example.dart

import 'package:pigeon/pigeon.dart';

@HostApi()
abstract class HostApi {
  bool sendMessage(String message);
  void showMessage(String message);
}

@FlutterApi()
abstract class FlutterApi {
  String getGreeting();
}
  1. Generate Pigeon Code:
flutter pub get
flutter pub run pigeon --input pigeon_example.dart --output ./lib/pigeon_example.dart.pigeon.dart
  1. Implement Host Code: For Android (Kotlin):
// MainActivity.kt
import com.example.pigeonexample.HostApi

class MainActivity : FlutterActivity() {
  private val hostApi by lazy {
    object : HostApi {
      override fun sendMessage(message: String): Boolean {
        Log.d("MainActivity", "Received message from Flutter: $message")
        return true
      }

      override fun showMessage(message: String) {
        Log.d("MainActivity", "Sending message to Flutter: $message")
        val intent = Intent(this@MainActivity, FlutterMessageActivity::class.java)
        intent.putExtra("message", message)
        startActivity(intent)
      }
    }
  }

  override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    Pigeon.HostApi.setup(flutterEngine.dartExecutor.binaryMessenger, hostApi)
  }
}

For iOS (Swift):

// ViewController.swift
import Foundation
import Pigeon

class ViewController: UIViewController {
  let flutterApi = Pigeon.FlutterApi()

  override func viewDidLoad() {
    flutterApi.getGreeting(call: { result in
      print("Received greeting from Flutter: \(result)")
    })
  }

  @IBAction func sendMessageToFlutter(_ sender: UIButton) {
    hostApi.sendMessage(message: "Hello from iOS")
  }
}
  1. Call Pigeon Methods in Flutter:
// main.dart
import 'package:pigeon_example/pigeon_example.dart.pigeon.dart';

void main() {
  FlutterApi flutterApi = FlutterApi();
  print(flutterApi.getGreeting());
}

Conclusion

Pigeon provides a powerful and convenient way to facilitate type-safe and efficient communication between Flutter and native platforms. Its code generation capabilities, error handling, and cross-platform support make it an invaluable tool for Flutter developers.

Flutter News Hub