tree: b0ef6c3437727e152d842f13bc465541cb28c67c [path history] [tgz]
  1. app/
  2. lib/
  3. pubspec.yaml
  4. README.md
packages/pigeon/example/README.md

Pigeon Examples

The examples here will cover basic usage. For a more thorough set of examples, check the core_tests pigeon file and platform test folder (shared_test_plugin_code and alternate_language_test_plugin especially).

Invocation

Begin by configuring pigeon at the top of the .dart input file. In actual use, you would include only the languages needed for your project.

@ConfigurePigeon(PigeonOptions(
  dartOut: 'lib/src/messages.g.dart',
  dartOptions: DartOptions(),
  cppOptions: CppOptions(namespace: 'pigeon_example'),
  cppHeaderOut: 'windows/runner/messages.g.h',
  cppSourceOut: 'windows/runner/messages.g.cpp',
  kotlinOut:
      'android/app/src/main/kotlin/dev/flutter/pigeon_example_app/Messages.g.kt',
  kotlinOptions: KotlinOptions(),
  javaOut: 'android/app/src/main/java/io/flutter/plugins/Messages.java',
  javaOptions: JavaOptions(),
  swiftOut: 'ios/Runner/Messages.g.swift',
  swiftOptions: SwiftOptions(),
  objcHeaderOut: 'macos/Runner/messages.g.h',
  objcSourceOut: 'macos/Runner/messages.g.m',
  // Set this to a unique prefix for your plugin or application, per Objective-C naming conventions.
  objcOptions: ObjcOptions(prefix: 'PGN'),
  copyrightHeader: 'pigeons/copyright.txt',
  dartPackageName: 'pigeon_example_package',
))

Then make a simple call to run pigeon on the Dart file containing your definitions.

flutter pub run pigeon --input path/to/input.dart

HostApi Example

This example gives an overview of how to use Pigeon to call into the host platform from Flutter.

Dart input

This is the Pigeon file that describes the interface that will be used to call from Flutter to the host-platform.

enum Code { one, two }

class MessageData {
  MessageData({required this.code, required this.data});
  String? name;
  String? description;
  Code code;
  Map<String?, String?> data;
}

@HostApi()
abstract class ExampleHostApi {
  String getHostLanguage();

  // These annotations create more idiomatic naming of methods in Objc and Swift.
  @ObjCSelector('addNumber:toNumber:')
  @SwiftFunction('add(_:to:)')
  int add(int a, int b);

  @async
  bool sendMessage(MessageData message);
}

Dart

This is the code that will use the generated Dart code to make calls from Flutter to the host platform.

final ExampleHostApi _api = ExampleHostApi();

/// Calls host method `add` with provided arguments.
Future<int> add(int a, int b) async {
  try {
    return await _api.add(a, b);
  } catch (e) {
    // handle error.
    return 0;
  }
}

/// Sends message through host api using `MessageData` class
/// and api `sendMessage` method.
Future<bool> sendMessage(String messageText) {
  final MessageData message = MessageData(
    code: Code.one,
    data: <String?, String?>{'header': 'this is a header'},
    description: 'uri text',
  );
  try {
    return _api.sendMessage(message);
  } catch (e) {
    // handle error.
    return Future<bool>(() => true);
  }
}

Swift

This is the code that will use the generated Swift code to receive calls from Flutter. packages/pigeon/example/app/ios/Runner/AppDelegate.swift

// This extension of Error is required to do use FlutterError in any Swift code.
extension FlutterError: Error {}

private class PigeonApiImplementation: ExampleHostApi {
  func getHostLanguage() throws -> String {
    return "Swift"
  }

  func add(_ a: Int64, to b: Int64) throws -> Int64 {
    if a < 0 || b < 0 {
      throw FlutterError(code: "code", message: "message", details: "details")
    }
    return a + b
  }

  func sendMessage(message: MessageData, completion: @escaping (Result<Bool, Error>) -> Void) {
    if message.code == Code.one {
      completion(.failure(FlutterError(code: "code", message: "message", details: "details")))
      return
    }
    completion(.success(true))
  }
}

Kotlin

private class PigeonApiImplementation : ExampleHostApi {
  override fun getHostLanguage(): String {
    return "Kotlin"
  }

  override fun add(a: Long, b: Long): Long {
    if (a < 0L || b < 0L) {
      throw FlutterError("code", "message", "details")
    }
    return a + b
  }

  override fun sendMessage(message: MessageData, callback: (Result<Boolean>) -> Unit) {
    if (message.code == Code.ONE) {
      callback(Result.failure(FlutterError("code", "message", "details")))
      return
    }
    callback(Result.success(true))
  }
}

C++

class PigeonApiImplementation : public ExampleHostApi {
 public:
  PigeonApiImplementation() {}
  virtual ~PigeonApiImplementation() {}

  ErrorOr<std::string> GetHostLanguage() override { return "C++"; }
  ErrorOr<int64_t> Add(int64_t a, int64_t b) {
    if (a < 0 || b < 0) {
      return FlutterError("code", "message", "details");
    }
    return a + b;
  }
  void SendMessage(const MessageData& message,
                   std::function<void(ErrorOr<bool> reply)> result) {
    if (message.code == Code.one) {
      result(FlutterError("code", "message", "details"));
      return;
    }
    result(true);
  }
};

FlutterApi Example

This example gives an overview of how to use Pigeon to call into the Flutter app from the host platform.

Dart input

@FlutterApi()
abstract class MessageFlutterApi {
  String flutterMethod(String? aString);
}

Dart

This is the code that will use the generated Dart code to handle calls made to Flutter from the host platform.

class _ExampleFlutterApi implements MessageFlutterApi {
  @override
  String flutterMethod(String? aString) {
    return aString ?? '';
  }
}
// ยทยทยท
  MessageFlutterApi.setup(_ExampleFlutterApi());

Swift

private class PigeonFlutterApi {
  var flutterAPI: MessageFlutterApi

  init(binaryMessenger: FlutterBinaryMessenger) {
    flutterAPI = MessageFlutterApi(binaryMessenger: binaryMessenger)
  }

  func callFlutterMethod(
    aString aStringArg: String?, completion: @escaping (Result<String, Error>) -> Void
  ) {
    flutterAPI.flutterMethod(aString: aStringArg) {
      completion(.success($0))
    }
  }
}

Kotlin

private class PigeonFlutterApi {

  var flutterApi: MessageFlutterApi? = null

  constructor(binding: FlutterPlugin.FlutterPluginBinding) {
    flutterApi = MessageFlutterApi(binding.getBinaryMessenger())
  }

  fun callFlutterMethod(aString: String, callback: (Result<String>) -> Unit) {
    flutterApi!!.flutterMethod(aString) { echo -> callback(Result.success(echo)) }
  }
}

C++

void TestPlugin::CallFlutterMethod(
    String aString, std::function<void(ErrorOr<int64_t> reply)> result) {
  MessageFlutterApi->FlutterMethod(
      aString, [result](String echo) { result(echo); },
      [result](const FlutterError& error) { result(error); });
}

Swift / Kotlin Plugin Example

A downloadable example of using Pigeon to create a Flutter Plugin with Swift and Kotlin can be found at gaaclarke/flutter_plugin_example.

Swift / Kotlin Add-to-app Example

A full example of using Pigeon for add-to-app with Swift on iOS can be found at samples/add_to_app/books.

Video player plugin

A full real-world example can also be found in the video_player plugin.