flutter-interoperating-with-native-apis
Original:🇺🇸 English
Translated
Interoperates with native platform APIs on Android, iOS, and the web. Use when accessing device-specific features not available in Dart or calling existing native code.
144installs
Sourceflutter/skills
Added on
NPX Install
npx skill4agent add flutter/skills flutter-interoperating-with-native-apisTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →Integrating Platform-Specific Code in Flutter
Contents
- Core Concepts & Terminology
- Binding to Native C/C++ Code (FFI)
- Implementing Platform Channels & Pigeon
- Hosting Native Platform Views
- Integrating Web Content & Wasm
- Workflows
Core Concepts & Terminology
- FFI (Foreign Function Interface): The library used to bind Dart directly to native C/C++ APIs.
dart:ffi - Platform Channel: The asynchronous message-passing system (,
MethodChannel) connecting the Dart client (UI) to the host platform (Kotlin/Java, Swift/Objective-C, C++).BasicMessageChannel - Pigeon: A code-generation tool that creates type-safe Platform Channels.
- Platform View: A mechanism to embed native UI components (e.g., Android , iOS
View) directly into the Flutter widget tree.UIView - JS Interop: The modern, Wasm-compatible approach to interacting with JavaScript and DOM APIs using and
package:web.dart:js_interop
Binding to Native C/C++ Code (FFI)
Use FFI to execute high-performance native code or utilize existing C/C++ libraries without the overhead of asynchronous Platform Channels.
Project Setup
- If creating a standard C/C++ integration (Recommended since Flutter 3.38): Use the template. This utilizes
package_ffihooks to compile native code, eliminating the need for OS-specific build files (CMake, build.gradle, podspec).build.dartbashflutter create --template=package_ffi <package_name> - If requiring access to the Flutter Plugin API or Play Services: Use the legacy template.
plugin_ffibashflutter create --template=plugin_ffi <plugin_name>
Implementation Rules
- Symbol Visibility: Always mark C++ symbols with and prevent linker discarding during link-time optimization (LTO).
extern "C"cppextern "C" __attribute__((visibility("default"))) __attribute__((used)) - Dynamic Library Naming (Apple Platforms): Ensure your hook produces the exact same filename across all target architectures (e.g.,
build.dartvsarm64) and SDKs (x86_64vsiphoneos). Do not append architecture suffixes to theiphonesimulatoror.dylibnames..framework - Binding Generation: Always use to generate Dart bindings from your C headers (
package:ffigen). Configure this in.h.ffigen.yaml
Implementing Platform Channels & Pigeon
Use Platform Channels when you need to interact with platform-specific APIs (e.g., Battery, Bluetooth, OS-level services) using the platform's native language.
Pigeon (Type-Safe Channels)
Always prefer over raw implementations for complex or frequently used APIs.
package:pigeonMethodChannel- Define the messaging protocol in a standalone Dart file using Pigeon annotations ().
@HostApi() - Generate the host (Kotlin/Swift/C++) and client (Dart) code.
- Implement the generated interfaces on the native side.
Threading Rules
- Main Thread Requirement: Always invoke channel methods destined for Flutter on the platform's main thread (UI thread).
- Background Execution: If executing channel handlers on a background thread (Android/iOS), you must use the Task Queue API ().
makeBackgroundTaskQueue() - Isolates: To use plugins/channels from a Dart background , ensure it is registered using
Isolate.BackgroundIsolateBinaryMessenger.ensureInitialized(rootIsolateToken)
Hosting Native Platform Views
Use Platform Views to embed native UI components (e.g., Google Maps, native video players) into the Flutter widget tree.
Android Platform Views
Evaluate the trade-offs between the two rendering modes and select the appropriate one:
- If requiring perfect fidelity, accessibility, or SurfaceView support: Use Hybrid Composition (+
PlatformViewLink). This appends the native view to the hierarchy but may reduce Flutter's rendering performance.AndroidViewSurface - If prioritizing Flutter rendering performance and transformations: Use Texture Layer (). This renders the native view into a texture. Note: Quick scrolling may drop frames, and
AndroidViewis problematic.SurfaceView
iOS Platform Views
- iOS exclusively uses Hybrid Composition.
- Implement and
FlutterPlatformViewFactoryin Swift or Objective-C.FlutterPlatformView - Use the widget on the Dart side.
UiKitView - Limitation: and
ShaderMaskwidgets cannot be applied to iOS Platform Views.ColorFiltered
Integrating Web Content & Wasm
Flutter Web supports compiling to WebAssembly (Wasm) for improved performance and multi-threading.
Wasm Compilation
- Compile to Wasm using: .
flutter build web --wasm - Server Configuration: To enable multi-threading, configure your HTTP server to emit the following headers:
- (or
Cross-Origin-Embedder-Policy: credentialless)require-corp Cross-Origin-Opener-Policy: same-origin
- Limitation: WasmGC is not currently supported on iOS browsers (WebKit limitation). Flutter will automatically fall back to JavaScript if WasmGC is unavailable.
Web Interop
- If writing new web-specific code: Strictly use and
package:web.dart:js_interop - Do NOT use: ,
dart:html, ordart:js. These are incompatible with Wasm compilation.package:js - Embedding HTML: Use to inject arbitrary HTML elements (like
HtmlElementView.fromTagName) into the Flutter Web DOM.<video>
Workflows
Workflow: Creating a Native FFI Integration
Use this workflow when binding to a C/C++ library.
- Task Progress:
- 1. Run .
flutter create --template=package_ffi <name> - 2. Place C/C++ source code in the directory.
src/ - 3. Ensure all exported C++ functions are wrapped in and visibility attributes.
extern "C" - 4. Configure to point to your header files.
ffigen.yaml - 5. Run to generate Dart bindings.
dart run ffigen - 6. Modify if linking against pre-compiled or system libraries.
hook/build.dart - 7. Run validator -> -> review errors -> fix.
flutter test
- 1. Run
Workflow: Implementing a Type-Safe Platform Channel (Pigeon)
Use this workflow when you need to call Kotlin/Swift APIs from Dart.
- Task Progress:
- 1. Add to
pigeon.dev_dependencies - 2. Create and define data classes and
pigeons/messages.dartabstract classes.@HostApi() - 3. Run the Pigeon generator script to output Dart, Kotlin, and Swift files.
- 4. Android: Implement the generated interface in or your Plugin class.
MainActivity.kt - 5. iOS: Implement the generated protocol in or your Plugin class.
AppDelegate.swift - 6. Dart: Import the generated Dart file and call the API methods.
- 7. Run validator -> verify cross-platform compilation -> review errors -> fix.
- 1. Add
Workflow: Embedding a Native Platform View
Use this workflow when embedding a native UI component (e.g., a native map or camera view).
- Task Progress:
- 1. Dart: Create a widget that conditionally returns (or
AndroidView) for Android, andPlatformViewLinkfor iOS based onUiKitView.defaultTargetPlatform - 2. Android: Create a class implementing that returns the native Android
PlatformView.View - 3. Android: Create a and register it in
PlatformViewFactory.configureFlutterEngine - 4. iOS: Create a class implementing that returns the native
FlutterPlatformView.UIView - 5. iOS: Create a and register it in
FlutterPlatformViewFactory.application:didFinishLaunchingWithOptions: - 6. Run validator -> test on physical Android and iOS devices -> review UI clipping/scrolling issues -> fix.
- 1. Dart: Create a widget that conditionally returns