DartNative serves as a powerful bridge connecting Dart to native APIs, efficiently replacing the low-performing Flutter channels with swift and concise code. Whether you’re developing an iOS, macOS, or Android application, DartNative has you covered with its dynamic capabilities.
Key Features of DartNative
- Dynamic Synchronous & Asynchronous Channeling: DartNative enables seamless calls to any native API, supporting both synchronous and asynchronous operations.
- Direct Multi-Language Interface Calls: Unlike Flutter channels, it eliminates the need for serialization of parameters and return values, offering direct calls and automatic object marshalling.
- Dart Finalizer Support: Even if you’re using previous versions of Flutter, DartNative allows the use of Dart finalizers.
- Auto-Generated Bridging Code: With automatic type conversion, DartNative minimizes the length and complexity of bridging code compared to Flutter channels.
Getting Started: Basic Usage
To start working with DartNative, begin by adding it to your project dependencies along with build_runner in your dev_dependencies. Below is a simple example of how Dart communicates with native APIs:
1. Setting Up Dart to Call Native APIs
Use the following code to call a native interface method:
dart
final interface = Interface(MyFirstInterface);
// Example for string type.
String helloWorld() {
return interface.invokeMethodSync(hello, args: ['world']);
}
// Example for num type.
Future sum(int a, int b) async {
return interface.invokeMethod('sum', args: [a, b]);
}
In this analogy, think of Dart as a friendly librarian that communicates with various rooms (native code). When you ask for a book (method), the librarian can directly retrieve or summon it, without waiting for any complicated procedures (serialization)—making the process seamless and efficient.
2. Corresponding Native Code
For iOS, your Objective-C implementation would look like this:
objectivec
@implementation DNInterfaceDemo
// Register interface name.
InterfaceEntry(MyFirstInterface)
// Register method hello.
InterfaceMethod(hello, myHello:(NSString *)str) {
return [NSString stringWithFormat:@"hello %@!", str];
}
// Register method sum.
InterfaceMethod(sum, addA:(int32_t)a withB:(int32_t)b) {
return @(a + b);
}
@end
And for Android, the Java implementation would be:
java
load libdart_native.so;
DartNativePlugin.loadSo();
@InterfaceEntry(name = "MyFirstInterface")
public class InterfaceDemo extends DartNativeInterface {
@InterfaceMethod(name = "hello")
public String hello(String str) {
return "hello " + str;
}
@InterfaceMethod(name = "sum")
public int sum(int a, int b) {
return a + b;
}
}
Advanced Usage: Invoke Methods Dynamically
Once you are comfortable calling methods, you can extend your DartNative experience by invoking methods dynamically:
- Add DartNative to dependencies and Build_runner to dev_dependencies.
- Generate Dart wrapper code using @dartnativecodegen or manually write Dart code.
- Generate code for automatic type conversion using dart_native_gen.
- Implement the generated functions in your main application. Utilize the auto-generated binding code for seamless integration.
Troubleshooting Common Issues
In case you run into any issues, here are some troubleshooting tips:
- Failed to lookup symbol (dlsym(RTLD_DEFAULT, InitDartApiDL): symbol not found): This error often indicates a configuration issue. Solutions include:
- Use a dynamic library by adding
use_frameworks!in your Podfile. - Adjust your Target Runner’s Build Settings to switch the Strip Style from All Symbols to Non-Global Symbols.
- Use a dynamic library by adding
- If you encounter problems with method calls, ensure you have properly registered all your methods in native APIs.
For more insights, updates, or to collaborate on AI development projects, stay connected with fxis.ai.
Conclusion
With DartNative, the complexity of bridging Dart to native APIs is drastically reduced, providing a clean and efficient way to harness the capabilities of native languages within your Flutter applications.
At fxis.ai, we believe that such advancements are crucial for the future of AI, as they enable more comprehensive and effective solutions. Our team is continually exploring new methodologies to push the envelope in artificial intelligence, ensuring that our clients benefit from the latest technological innovations.

