Flutter wrapper
On this page, we will start creating the Flutter wrapper around our Dart-only library package. We start with the plugin_ffi Flutter template since it is somewhat similar to what we need, but we will need to modify it significantly in the coming steps. Configuring the build processes for each supported platform is also a bit involved, so those are covered individually in the coming pages.
Run flutter create --help
to see all the available options; you may want to set some (like --org
).
Finally, in the packages
folder, run the following, adding any other options you choose
and replacing library_name
with your library name:
flutter create --template=plugin_ffi --platforms=android,ios,macos,linux,windows --org=com.example flutter_library_name
Additional setup steps
- Add your Dart-only base as a dependency in your new Flutter package's
pubspec.yaml
. Use the version syntax, e.g.^1.0.0
. Melos will take care of the dependency resolution for us. - If you choose to have integration testing in CI (recommended),
add an
integration_test
folder to your Flutter package's and/or Flutter example package's root directory, then add the following to thepubspec.yaml
of the applicable package(s):
dev_dependencies:
flutter_test:
sdk: flutter
integration_test:
sdk: flutter
- In
/packages/flutter_library_name/lib/flutter_library_name.dart
, add the following near the top of the file, replacinglibrary_name
with your Dart-only package's name:
export 'package:library_name/library_name.dart';
This re-exports your Dart-only package to users of your Flutter package,
so they only need to do one flutter pub add
.
- Finally, we will need to write some code to be able to handle FFI in Flutter.
Modify the following as needed (replacing
library_name
andLibraryName
with your library name).
// lib/src/ffi/stub.dart
Object createLibraryImpl() => throw UnimplementedError();
// lib/src/ffi/io.dart
import 'dart:ffi';
import 'dart:io';
DynamicLibrary createLibraryImpl() {
const base = 'library_name';
if (Platform.isIOS || Platform.isMacOS) {
return DynamicLibrary.open('$base.framework/$base');
} else if (Platform.isWindows) {
return DynamicLibrary.open('$base.dll');
} else {
return DynamicLibrary.open('lib$base.so');
}
}
// lib/src/ffi/web.dart
import 'package:library_name/library_name.dart';
WasmModule createLibraryImpl() {
// TODO add web support. See:
// https://github.com/fzyzcjy/flutter_rust_bridge/blob/master/frb_example/with_flutter/lib/ffi.web.dart
throw UnsupportedError('Web support is not provided yet.');
}
// lib/src/ffi.dart
import 'package:library_name/library_name.dart';
import 'ffi/stub.dart'
if (dart.library.io) 'ffi/io.dart'
if (dart.library.js_interop) 'ffi/web.dart';
LibraryName createLib() =>
createWrapper(createLibraryImpl());
- Run
melos bs
Now, inside your Flutter library, you can call createLib()
to get an instance of the FRB-generated Dart class!
However, it won't work just yet; we will wire up our Flutter package to use our Rust binaries in the next subsection.