Skip to content

Commit d3c0d5f

Browse files
authored
[Pigeon] readme updates (#3705)
Updates README's to better reflect modern pigeon and it's usage. Very open to feedback on this, please let me know what could be better, clearer, or is just missing from this documentation. I don't expect to be able to cover all uses with this, if people want to see all possibilities, I think looking into our very thorough integration tests will provide them with anything they could need (all of which is linked in the example README). fixes flutter/flutter#66511 partial work for flutter/flutter#123851 fixes flutter/flutter#108531 fixes flutter/flutter#92641
1 parent d6e0d1f commit d3c0d5f

File tree

37 files changed

+2019
-421
lines changed

37 files changed

+2019
-421
lines changed

packages/pigeon/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 10.1.1
2+
3+
* Updates README to better reflect modern usage.
4+
15
## 10.1.0
26

37
* [objc] Adds macOS support to facilitate code sharing with existing iOS plugins.

packages/pigeon/README.md

Lines changed: 88 additions & 216 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,107 @@
11
# Pigeon
22

33
Pigeon is a code generator tool to make communication between Flutter and the
4-
host platform type-safe, easier and faster.
4+
host platform type-safe, easier, and faster.
55

6-
## Supported Platforms
6+
Pigeon removes the necessity to manage strings across multiple platforms and languages.
7+
It also improves efficiency over common method channel patterns. Most importantly though,
8+
it removes the need to write custom platform channel code, since pigeon generates it for you.
79

8-
Currently Pigeon supports generating:
10+
For usage examples, see the [Example README](./example/README.md).
11+
12+
## Features
13+
14+
### Supported Platforms
15+
16+
Currently pigeon supports generating:
917
* Kotlin and Java code for Android
1018
* Swift and Objective-C code for iOS and macOS
1119
* C++ code for Windows
1220

13-
## Runtime Requirements
21+
### Supported Datatypes
22+
23+
Pigeon uses the `StandardMessageCodec` so it supports
24+
[[any datatype platform channels support](https://flutter.dev/docs/development/platform-integration/platform-channels#codec)].
25+
26+
Custom classes and nested datatypes are also supported.
27+
28+
#### Enums
29+
30+
Pigeon currently supports enum generation in class fields only.
31+
See issue: [87307](https://github.com/flutter/flutter/issues/87307).
32+
33+
### Synchronous and Asynchronous methods
34+
35+
While all calls across platform channel APIs (such as pigeon methods) are asynchronous,
36+
pigeon methods can be written on the native side as synchronous methods,
37+
to make it simpler to always reply exactly once.
1438

15-
Pigeon generates all the code that is needed to communicate between Flutter and
16-
the host platform, there is no extra runtime requirement. A plugin author
17-
doesn't need to worry about conflicting versions of Pigeon.
39+
If asynchronous methods are needed, the `@async` annotation can be used. This will require
40+
results or errors to be returned via a provided callback. [Example](./example/README.md#HostApi_Example).
41+
42+
### Error Handling
43+
44+
#### Kotlin, Java and Swift
45+
46+
All Host API exceptions are translated into Flutter `PlatformException`.
47+
* For synchronous methods, thrown exceptions will be caught and translated.
48+
* For asynchronous methods, there is no default exception handling; errors
49+
should be returned via the provided callback.
50+
51+
To pass custom details into `PlatformException` for error handling,
52+
use `FlutterError` in your Host API. [Example](./example/README.md#HostApi_Example).
53+
54+
To use `FlutterError` in Swift you must first extend a standard error.
55+
[Example](./example/README.md#AppDelegate.swift).
56+
57+
#### Objective-C and C++
58+
59+
Host API errors can be sent using the provided `FlutterError` class (translated into `PlatformException`).
60+
61+
For synchronous methods:
62+
* Objective-C - Set the `error` argument to a `FlutterError` reference.
63+
* C++ - Return a `FlutterError`.
64+
65+
For async methods:
66+
* Return a `FlutterError` through the provided callback.
67+
68+
69+
### Task Queue
70+
71+
When targeting a Flutter version that supports the
72+
[TaskQueue API](https://docs.flutter.dev/development/platform-integration/platform-channels?tab=type-mappings-kotlin-tab#channels-and-platform-threading)
73+
the threading model for handling HostApi methods can be selected with the
74+
`TaskQueue` annotation.
1875

1976
## Usage
2077

21-
1) Add Pigeon as a `dev_dependency`.
78+
1) Add pigeon as a `dev_dependency`.
2279
1) Make a ".dart" file outside of your "lib" directory for defining the
2380
communication interface.
2481
1) Run pigeon on your ".dart" file to generate the required Dart and
2582
host-language code: `flutter pub get` then `flutter pub run pigeon`
26-
with suitable arguments (see [example](./example)).
83+
with suitable arguments. [Example](./example/README.md#Invocation).
2784
1) Add the generated Dart code to `./lib` for compilation.
2885
1) Implement the host-language code and add it to your build (see below).
2986
1) Call the generated Dart methods.
3087

88+
### Rules for defining your communication interface
89+
[Example](./example/README.md#HostApi_Example)
90+
91+
1) The file should contain no method or function definitions, only declarations.
92+
1) Custom classes used by APIs are defined as classes with fields of the
93+
supported datatypes (see the supported Datatypes section).
94+
1) APIs should be defined as an `abstract class` with either `@HostApi()` or
95+
`@FlutterApi()` as metadata. `@HostApi()` being for procedures that are defined
96+
on the host platform and the `@FlutterApi()` for procedures that are defined in Dart.
97+
1) Method declarations on the API classes should have arguments and a return
98+
value whose types are defined in the file, are supported datatypes, or are
99+
`void`.
100+
1) Generics are supported, but can currently only be used with nullable types
101+
(example: `List<int?>`).
102+
1) Objc and Swift have special naming conventions that can be utilized with the
103+
`@ObjCSelector` and `@SwiftFunction` respectively.
104+
31105
### Flutter calling into iOS steps
32106

33107
1) Add the generated Objective-C or Swift code to your Xcode project for compilation
@@ -58,214 +132,12 @@ doesn't need to worry about conflicting versions of Pigeon.
58132

59133
### Calling into Flutter from the host platform
60134

61-
Flutter also supports calling in the opposite direction. The steps are similar
135+
Pigeon also supports calling in the opposite direction. The steps are similar
62136
but reversed. For more information look at the annotation `@FlutterApi()` which
63-
denotes APIs that live in Flutter but are invoked from the host platform.
64-
65-
### Rules for defining your communication interface
66-
67-
1) The file should contain no method or function definitions, only declarations.
68-
1) Custom classes used by APIs are defined as classes with fields of the
69-
supported datatypes (see the supported Datatypes section).
70-
1) APIs should be defined as an `abstract class` with either `HostApi()` or
71-
`FlutterApi()` as metadata. The former being for procedures that are defined
72-
on the host platform and the latter for procedures that are defined in Dart.
73-
1) Method declarations on the API classes should have arguments and a return
74-
value whose types are defined in the file, are supported datatypes, or are
75-
`void`.
76-
1) Generics are supported, but can currently only be used with nullable types
77-
(example: `List<int?>`).
78-
79-
## Supported Datatypes
80-
81-
Pigeon uses the `StandardMessageCodec` so it supports any datatype Platform
82-
Channels supports
83-
[[documentation](https://flutter.dev/docs/development/platform-integration/platform-channels#codec)].
84-
Nested datatypes are supported, too.
85-
86-
## Features
87-
88-
### Asynchronous Handlers
89-
90-
By default Pigeon will generate synchronous handlers for messages and
91-
asynchronous methods. If you want a handler to be able to respond to a message
92-
asynchronously you can use the @async annotation as of version 0.1.20.
93-
94-
Example:
95-
96-
```dart
97-
class Value {
98-
int? number;
99-
}
100-
101-
@HostApi()
102-
abstract class Api2Host {
103-
@async
104-
Value calculate(Value value);
105-
}
106-
```
107-
108-
Generates:
109-
110-
```objc
111-
// Objective-C
112-
@protocol Api2Host
113-
-(void)calculate:(nullable Value *)input
114-
completion:(void(^)(Value *_Nullable, FlutterError *_Nullable))completion;
115-
@end
116-
```
117-
118-
```swift
119-
// Swift
120-
121-
/** Generated interface from Pigeon that represents a handler of messages from Flutter.*/
122-
protocol Api2Host {
123-
func calculate(value: Value, completion: @escaping (Value) -> Void)
124-
}
125-
```
126-
127-
```java
128-
// Java
129-
public interface Result<T> {
130-
void success(T result);
131-
}
132-
133-
/** Generated interface from Pigeon that represents a handler of messages from Flutter.*/
134-
public interface Api2Host {
135-
void calculate(Value arg, Result<Value> result);
136-
}
137-
```
138-
139-
```kotlin
140-
// Kotlin
141-
142-
/** Generated interface from Pigeon that represents a handler of messages from Flutter.*/
143-
interface Api2Host {
144-
fun calculate(value: Value, callback: (Result<Value>) -> Unit)
145-
}
146-
```
147-
148-
```c++
149-
// C++
150-
151-
/** Generated class from Pigeon that represents a handler of messages from Flutter.*/
152-
class Api2Host {
153-
public:
154-
virtual void calculate(Value value, flutter::MessageReply<Value> result) = 0;
155-
}
156-
```
157-
158-
### Null Safety (NNBD)
159-
160-
Pigeon supports generating null-safe code, but it doesn't yet support:
161-
162-
1) Nullable generics type arguments
163-
1) Nullable enum arguments to methods
164-
165-
### Enums
166-
167-
Pigeon supports enum generation in class fields. For example:
168-
```dart
169-
enum State {
170-
pending,
171-
success,
172-
error,
173-
}
174-
175-
class StateResult {
176-
String? errorMessage;
177-
State? state;
178-
}
179-
180-
@HostApi()
181-
abstract class Api {
182-
StateResult queryState();
183-
}
184-
```
185-
186-
### Primitive Data-types
187-
188-
Prior to version 1.0 all arguments to API methods had to be wrapped in a class, now they can be used directly. For example:
189-
190-
```dart
191-
@HostApi()
192-
abstract class Api {
193-
Map<String?, int?> makeMap(List<String?> keys, List<String?> values);
194-
}
195-
```
196-
197-
### TaskQueues
198-
199-
When targeting a Flutter version that supports the
200-
[TaskQueue API](https://docs.flutter.dev/development/platform-integration/platform-channels?tab=type-mappings-kotlin-tab#channels-and-platform-threading)
201-
the threading model for handling HostApi methods can be selected with the
202-
`TaskQueue` annotation:
203-
204-
```dart
205-
@HostApi()
206-
abstract class Api2Host {
207-
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
208-
int add(int x, int y);
209-
}
210-
```
211-
212-
### Error Handling
213-
214-
#### Kotlin, Java and Swift
215-
216-
All Host API exceptions are translated into Flutter `PlatformException`.
217-
* For synchronous methods, thrown exceptions will be caught and translated.
218-
* For asynchronous methods, there is no default exception handling; errors should be returned via the provided callback.
219-
220-
To pass custom details into `PlatformException` for error handling, use `FlutterError` in your Host API.
221-
For example:
222-
223-
```kotlin
224-
// Kotlin
225-
class MyApi : GeneratedApi {
226-
// For synchronous methods
227-
override fun doSomething() {
228-
throw FlutterError('error_code', 'message', 'details')
229-
}
230-
231-
// For async methods
232-
override fun doSomethingAsync(callback: (Result<Unit>) -> Unit) {
233-
callback(Result.failure(FlutterError('error_code', 'message', 'details'))
234-
}
235-
}
236-
```
237-
238-
#### Objective-C and C++
239-
240-
Likewise, Host API errors can be sent using the provided `FlutterError` class (translated into `PlatformException`).
241-
242-
For synchronous methods:
243-
* Objective-C - Assign the `error` argument to a `FlutterError` reference.
244-
* C++ - Return a `FlutterError` directly (for void methods) or within an `ErrorOr` instance.
245-
246-
For async methods:
247-
* Both - Return a `FlutterError` through the provided callback.
248-
249-
#### Handling the errors
250-
251-
Then you can implement error handling on the Flutter side:
252-
253-
```dart
254-
// Dart
255-
void doSomething() {
256-
try {
257-
myApi.doSomething()
258-
} catch (PlatformException e) {
259-
if (e.code == 'error_code') {
260-
// Perform custom error handling
261-
assert(e.message == 'message')
262-
assert(e.details == 'details')
263-
}
264-
}
265-
}
266-
```
137+
denotes APIs that live in Flutter but are invoked from the host platform.
138+
[Example](./example/README.md#FlutterApi_Example).
267139

268140
## Feedback
269141

270-
File an issue in [flutter/flutter](https://github.com/flutter/flutter) with the
271-
word "pigeon" in the title.
142+
File an issue in [flutter/flutter](https://github.com/flutter/flutter) with
143+
"[pigeon]" at the start of the title.

0 commit comments

Comments
 (0)