-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Add FFI and JNI support to Swift and Kotlin #11352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
b9b0b5e
e599d1e
726975d
f636cdb
72a305e
4e59659
e22c55a
3f0be1d
0d09615
e0f23a9
025376c
aa01700
6a0df05
022ed51
43f2e5a
5fd46e8
a0c56ab
2c252ae
5072a47
b0cd2ec
38bd37e
850cb2e
9bb4bc5
0c7ef63
110ab70
82065a8
9861c00
11daedd
e197fc0
cbf4096
935aa47
4e9541f
f30b44c
08a79f3
8cb51ac
ddc41c2
4ad3636
0a08ef5
5855b23
f99e64a
101fb0f
7309d17
24d0f23
21ad393
94a58c8
3fdd987
b920f50
7df481e
25021e7
4cbfdcd
8c75a36
655229c
80d8bbc
a57dd6f
4ded545
8698cb5
7355a96
45d8207
ad236e7
97b8e8c
38cffb2
ff33669
a2a80b5
b5b4506
1305a1d
a5ce9cc
6d92541
eba918b
8d55afd
5097bdc
0a5adee
a3e5531
51d7b7c
9ca1762
69c20d2
214299f
393c5c8
18f5c23
7b8e9ec
944a09a
d4d8f92
88bade6
4c90953
a5a1593
09d3960
b9f0e4d
6534809
05589c7
2a3c8d1
0a2c280
aabc90a
6ac09ea
31b0806
e3c9c69
246b1a3
6951605
d47a1ad
f422d9d
835f8f5
d765ce7
898ec56
5c53127
aa7372b
dd5e68c
e202db9
812c750
eff7d08
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| // Copyright 2013 The Flutter Authors | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| package dev.flutter.pigeon_example_app | ||
|
|
||
| // #docregion concurrency-style | ||
| suspend fun echoAsync(value: String): String { | ||
| return value | ||
| } | ||
| // #enddocregion concurrency-style |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| // Copyright 2013 The Flutter Authors | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| import Foundation | ||
|
|
||
| // #docregion callback-style | ||
| func echoAsync(_ value: String, completion: @escaping (Result<String, Error>) -> Void) { | ||
| completion(.success(value)) | ||
| } | ||
| // #enddocregion callback-style | ||
|
|
||
| // #docregion concurrency-style | ||
| func echoAsync(_ value: String) async throws -> String { | ||
| return value | ||
| } | ||
| // #enddocregion concurrency-style |
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should consider changing to two example apps, one that uses method-channel-based Pigeon, and one that use the FFI-based Pigeon. I would expect the common use case to just be one or the other, so putting both in the same app could be confusing.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have the infrastructure to handle two example apps?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, if you have |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| // Copyright 2013 The Flutter Authors | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| import 'package:pigeon/pigeon.dart'; | ||
|
|
||
| // #docregion config | ||
| @ConfigurePigeon( | ||
| PigeonOptions( | ||
| dartOptions: DartOptions(), | ||
| kotlinOptions: KotlinOptions(useJni: true), | ||
| swiftOptions: SwiftOptions(useFfi: true, ffiModuleName: 'my_plugin'), | ||
| ), | ||
| ) | ||
| // #enddocregion config | ||
| @HostApi() | ||
| abstract class NativeInteropExampleApi { | ||
| void doSomething(); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not actually seeing any generated code corresponding to this. Is this file unused except for excerpting? If so that's pretty confusing for anyone looking at the example to see how to use this. |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -526,6 +526,27 @@ class TypeDeclaration { | |
| /// Associated [AstProxyApi], if any. | ||
| final AstProxyApi? associatedProxyApi; | ||
|
|
||
| /// Returns the full annotated name of the type. | ||
| String getFullName({bool withNullable = true}) { | ||
| return '$baseName$typeArgumentsString${isNullable && withNullable ? '?' : ''}'; | ||
| } | ||
|
|
||
| /// Returns the Type Arguments in annotation form. | ||
| String get typeArgumentsString { | ||
|
tarrinneal marked this conversation as resolved.
|
||
| var typeArgumentString = '<'; | ||
| if (baseName == 'List') { | ||
| typeArgumentString += | ||
| typeArguments.firstOrNull?.getFullName() ?? 'Object?'; | ||
| } else if (baseName == 'Map') { | ||
| typeArgumentString += | ||
| '${typeArguments.firstOrNull?.getFullName() ?? 'Object?'}, ${typeArguments.lastOrNull?.getFullName() ?? 'Object?'}'; | ||
| } else { | ||
| return ''; | ||
| } | ||
| typeArgumentString += '>'; | ||
| return typeArgumentString; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can do |
||
| } | ||
|
|
||
| @override | ||
| int get hashCode { | ||
| // This has to be implemented because TypeDeclaration is used as a Key to a | ||
|
|
@@ -834,6 +855,8 @@ class Root extends Node { | |
| required this.classes, | ||
| required this.apis, | ||
| required this.enums, | ||
| this.lists = const <String, TypeDeclaration>{}, | ||
| this.maps = const <String, TypeDeclaration>{}, | ||
| this.containsHostApi = false, | ||
| this.containsFlutterApi = false, | ||
| this.containsProxyApi = false, | ||
|
|
@@ -842,7 +865,13 @@ class Root extends Node { | |
|
|
||
| /// Factory function for generating an empty root, usually used when early errors are encountered. | ||
| factory Root.makeEmpty() { | ||
| return Root(apis: <Api>[], classes: <Class>[], enums: <Enum>[]); | ||
| return Root( | ||
| apis: <Api>[], | ||
| classes: <Class>[], | ||
| enums: <Enum>[], | ||
| lists: <String, TypeDeclaration>{}, | ||
| maps: <String, TypeDeclaration>{}, | ||
| ); | ||
| } | ||
|
|
||
| /// All the classes contained in the AST. | ||
|
|
@@ -854,6 +883,12 @@ class Root extends Node { | |
| /// All of the enums contained in the AST. | ||
| List<Enum> enums; | ||
|
|
||
| /// All of the lists contained in the AST. | ||
| Map<String, TypeDeclaration> lists; | ||
|
|
||
| /// All of the maps contained in the AST. | ||
| Map<String, TypeDeclaration> maps; | ||
|
|
||
| /// Whether the root has any Host API definitions. | ||
| bool containsHostApi; | ||
|
|
||
|
|
@@ -876,6 +911,6 @@ class Root extends Node { | |
|
|
||
| @override | ||
| String toString() { | ||
| return '(Root classes:$classes apis:$apis enums:$enums)'; | ||
| return '(Root classes:$classes apis:$apis enums:$enums lists:$lists maps:$maps containsHostApi:$containsHostApi containsFlutterApi:$containsFlutterApi containsProxyApi:$containsProxyApi)'; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need significantly more changes to README.md than just adding a new section. See my comments in native_interop_guide.md, but at a high level: imagine you have never used Pigeon before, and you are reading the README as a starting point. What would your path from the start of this document need to look like in order to end up with an understanding of how to use NI-based Pigeon?