Introduction to the
Pigeon was released in Flutter 1.20. In order to solve the problem that the native code of Flutter is too troublesome and difficult to call, it is necessary to match function names and parameters on the basis of strings. This can be done by using this package. But there is still a difference with their own projects.
-
Securely communicate with native types
-
Reduce the amount of handwritten code through automatic generation
This article describes in detail how to use Pigeon to call a simple getPlatformVersion method implemented in Swift/Kotlin from the Flutter side. Sample projects are available here.
Create a Flutter app
$ flutter create -i swift -a kotlin flutter_pigeon
Copy the code
What does a Pigeon do
The Java/Objective-C interface protocol is automatically generated based on the parameters and return value information defined on the Dart side.
The native implementation is based on these interfaces to enable type-safe communication with the Flutter end.
This is similar to creating type definition files with TypeScript.
The installation
# pubspec.yamlDev_dependencies: pigeon: ^ 1.0.0Copy the code
Dart
First, create a DART file that defines communication with the native. Create a pigeon/schema.dart file in the root directory
// schema.dart
import 'package:pigeon/pigeon.dart';
class Version {
late String string;
}
@HostApi(a)abstract class Api {
Version getPlatformVersion();
}
Copy the code
Create a new script file run_pigeon
# run_pigeon.h
$ flutter pub run pigeon \
--input pigeon/schema.dart \
--dart_out lib/api_generated.dart \
--objc_header_out ios/Runner/Pigeon.h \
--objc_source_out ios/Runner/Pigeon.m \
--objc_prefix FLT \
--java_out android/app/src/main/java/io/flutter/plugins/Pigeon.java \
--java_package "io.flutter.plugins"
Copy the code
Run the script to automatically generate the corresponding interface file
$ ./run_pigeon.sh
Copy the code
Import and use the Dart file that Pigeon generated where native method functions need to be called
Kotlin
The API interface is written in a Java file that Pigeon generated, so create a class that implements it and pass it to the setup method.
// MainActivity.kt
package com.example.flutter_pigeon
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.Pigeon
class MainActivity: FlutterActivity() {
private class MyApi: Pigeon.Api {
override fun getPlatformVersion(a): Pigeon.Version {
var result = Pigeon.Version()
result.string = "Android ${android.os.Build.VERSION.RELEASE}"
return result
}
}
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
// 2. setup()
Pigeon.Api.setup(flutterEngine.dartExecutor.binaryMessenger, MyApi())
}
}
Copy the code
Swift
Add import statements to the bridge file ios/RunnerRunner-Bridging- header. h to make Pigeon’s Objective-C file visible to Swift
// ios / Runner / Runner-Bridging-Header.h
#import "Pigeon.h"
Copy the code
Since the API protocol is written in the generated file, create a class MyApi that implements the protocol
Create the swiftPigeonService. swift file to implement the protocol method
// SwiftPigeonService.swift
import Flutter
import UIKit
public class SwiftPigeonService: NSObject.FLTApi {
public func getPlatformVersionWithError(_ error: AutoreleasingUnsafeMutablePointer<FlutterError? >) -> FLTVersion? {
let result = FLTVersion.init()
result.string = "iOS " + UIDevice.current.systemVersion
return result
}
}
Copy the code
Instantiate the API in the AppDelegate and pass it to the setup method
// AppDelegate.swift
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication.didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
FLTApiSetup(controller.binaryMessenger, SwiftPigeonService())
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Copy the code
conclusion
-
Pigeon automatically generates parts of content associated with using MethodChannel. (Pigeon, technically, used a BasicMessageChannel.)
-
Predefined schemas allow type-safe communication with Native
-
The generated code is Java/Objective-C, but since Kotlin can call Java, Swift can call Objective-C
-
You don’t have to know the Dart side code (just call the automatically generated API)
-
You don’t have to know native code (just implement an automatically generated interface)
-
The video_player is already in use in the official plugin