one_for_all
OneForAll is a code generator tool to make communication between Flutter and the host platform type-safe, easier, and faster.
OneForAll removes the necessity to manage strings across multiple platforms and languages. It also improves efficiency over common method channel patterns. Most importantly though, it removes the need to write custom platform channel code, since OneForAll generates it for you.
For usage examples, see the mek_stripe_terminal package.
Features
Supported Platforms
Currently, one_for_all supports generating:
- Dart
- Kotlin code for Android
- Swift code for iOS and macOS
Getting started
Add these dependencies to your pubspec.yaml:
dependencies:
one_for_all:
dev_dependencies:
one_for_all_generator:
Usage
- Annotate a class with
HostApi
- Add an abstract method that returns a future
- Extend the generated class
@HostApi() class Terminal extends _$Terminal { Future<List<Reader>> fetchReaders(); }
- Generate code with:
- Default script
dart run one_for_all_generator \ --api-path=lib/terminal.dart \ --kotlin-output-file=android/src/main/Terminal.kt \ --kotlin-package=com.terminal --swift-output-file=ios/Classes/Terminal.swift
- Custom script
import 'package:one_for_all_generator/one_for_all_generator.dart'; void main() async { await OneForAll.from( options: const OneForAllOptions( apiFile: 'lib/terminal.dart', ), dartOptions: const DartOptions(), kotlinOptions: const KotlinOptions( outputFile: 'android/src/main/Terminal.kt', package: 'com.terminal', ), swiftOptions: const SwiftOptions( outputFile: 'ios/Classes/Terminal.swift', ), ).build(); }
- Default script
Generating methods async, sync or using callbacks
You can apply MethodApi annotation to yours to generate native methods in 3 different ways
@HostApi()
class Terminal extends _$Terminal {
@MethodApi(
kotlin: MethodApiType.<sync|async|callbacks>
swift: MethodApiType.<sync|async|callbacks>,
)
Future<List<Reader>> fetchReaders();
}
- sync: The method to be implemented will have the parameters equal to the method in dart and the return type equal to that of the Future of dart
- callbacks: Allows normal use of channels. The first parameter of the method to be implemented will be a Result with already implemented serialization and remaining parameters will be those of the method in dart. The method does not return anything.
- async: The method to be implemented will have the same parameters as dart but in kotlin it will be a
suspend
method instead in swift it will be anasync
method. The return type equal to that of the Future of dart.
Do you need to call flutter methods from native code?
Define your own class with the methods to be made available in the various platforms and implement them.
Methods must begin with on
or _on
@FlutterApi()
class _FlutterTerminal {
Future<String> onFetchToken() async {
return await httpClient.getToken();
}
}
Connect the channel to your implementation
final flutterTerminal = _FlutterTerminal();
setupFlutterTerminal(flutterTerminal);
Why was this package written if pigeon package exists?
The purpose of this package is to make it easy to implement new plugins.
Dual classes
- pigeon: you will need the schema of your class outside the
lib
directory and the code generated by pigeon. - one_for_all: you only have to write the abstract methods in your class and only what you are missing will be generated. This allows you to write one class already with all your public methods
Data class with non-final fields
- pigeon: Classes generated in dart have non-final fields
- one_for_all: Your classes are used directly. If you want to put final fields they will be final
Methods to data classes
- pigeon: You can't add methods to data classes since they will be generated based on the schema without the methods
- one_for_all: Your classes are used directly. If you want to put methods or getters you can do that
Write methods with named parameters
- pigeon: does not support nominal or positional parameters in methods
- one_for_all: full support for any type of dart parameter
How was the library written?
- pigeon: It is faster in code generation but uses the Visitor pattern to build your generated code
- one_for_all: It is slower in generating code but uses the same structure as build_runner, the Element classes.
Contributing
The code is formatted with a line/page length of 100 characters. Use conventional commits for your commits.