{"id":14956401,"url":"https://github.com/dart-native/dart_native","last_synced_at":"2026-01-11T04:48:57.275Z","repository":{"id":39911583,"uuid":"211798475","full_name":"dart-native/dart_native","owner":"dart-native","description":"Write iOS\u0026macOS\u0026Android Code using Dart. This package liberates you from redundant glue code and low performance of Flutter Channel.","archived":false,"fork":false,"pushed_at":"2024-05-21T04:38:36.000Z","size":116074,"stargazers_count":952,"open_issues_count":26,"forks_count":77,"subscribers_count":23,"default_branch":"master","last_synced_at":"2025-04-08T16:06:15.381Z","etag":null,"topics":["android","dart","dart-java","dart-native","dart-objc","dartffi","dartnative","dartobjc","ffi","flutter","ios","java","jni","macos","native","objective-c","runtime"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dart-native.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-30T07:13:26.000Z","updated_at":"2025-03-31T10:24:40.000Z","dependencies_parsed_at":"2024-06-21T16:53:54.567Z","dependency_job_id":"3624521d-dfc3-4240-a12a-7bcb65cb74ca","html_url":"https://github.com/dart-native/dart_native","commit_stats":null,"previous_names":["yulingtianxia/dart_objc"],"tags_count":57,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dart-native%2Fdart_native","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dart-native%2Fdart_native/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dart-native%2Fdart_native/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dart-native%2Fdart_native/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dart-native","download_url":"https://codeload.github.com/dart-native/dart_native/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254485025,"owners_count":22078764,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","dart","dart-java","dart-native","dart-objc","dartffi","dartnative","dartobjc","ffi","flutter","ios","java","jni","macos","native","objective-c","runtime"],"created_at":"2024-09-24T13:12:58.785Z","updated_at":"2026-01-11T04:48:57.269Z","avatar_url":"https://github.com/dart-native.png","language":"C","readme":"# DartNative\n\nDartNative operates as a bridge to communicate between Dart and native APIs.\n\nReplaces the low-performing Flutter channel with faster and more concise code.\n\n[![pub package](https://img.shields.io/pub/v/dart_native.svg)](https://pub.dev/packages/dart_native)\n[![Build Status](https://app.travis-ci.com/dart-native/dart_native.svg?branch=master)](https://app.travis-ci.com/dart-native/dart_native)\n[![Dart CI](https://github.com/dart-native/dart_native/actions/workflows/dart.yml/badge.svg)](https://github.com/dart-native/dart_native/actions/workflows/dart.yml)\n\n## Features\n\n### Dynamic synchronous \u0026 asynchronous channeling\n\nDartNative calls *any* native API *dynamically*. It supports both synchronous and asynchronous channeling. \n\n### Direct call between multi-language interfaces\n\nSerialization of parameters and return values like Flutter Channel is no longer required. DartNative provides direct calls and automatic object marshalling between language interfaces.\n\n### Dart finalizer\n\nDart finalizer is only supported above Flutter 3(Dart 2.17), but with DartNative it is available in Dart Flutter 2.2.0(Dart 2.13.0) and up.\n\n### Autogenerate succinct bridging code\n\nDartNative supports automatic type conversion so its bridging code is shorter \u0026 simpler than the Flutter channel.\n\nThe design and vision of this package:\n\n![](images/dartnative.png)\n\n## Requirements\n\n| DartNative Version | Flutter Requirements | Codegen Version |\n| --- | --- | --- |\n| 0.4.x - 0.7.x | Flutter 2.2.0 (Dart 2.13.0) | 2.x |\n| 0.3.x | Flutter 1.20.0 (Dart 2.9.1) | 1.2.x |\n| 0.2.x | Flutter 1.12.13 (Dart 2.7) | 1.x |\n\n## Supported Platforms\n\niOS \u0026 macOS \u0026 Android\n\n## Usage\n\n### Basic usage: Interface binding\n\nAdd ```dart_native``` to dependencies and ```build_runner``` to dev_dependencies. Then you can write code. Here are some examples:\n\n#### Dart calls Native\n\nDart code:\n\n```dart\nfinal interface = Interface(\"MyFirstInterface\");\n// Example for string type.\nString helloWorld() {\n    return interface.invokeMethodSync('hello', args: ['world']);\n}\n// Example for num type.\nFuture\u003cint\u003e sum(int a, int b) {\n    return interface.invokeMethod('sum', args: [a, b]);\n}\n```\n\nCorresponding Objective-C code:\n\n```objectivec\n@implementation DNInterfaceDemo\n\n// Register interface name.\nInterfaceEntry(MyFirstInterface)\n\n// Register method \"hello\".\nInterfaceMethod(hello, myHello:(NSString *)str) {\n    return [NSString stringWithFormat:@\"hello %@!\", str];\n}\n\n// Register method \"sum\".\nInterfaceMethod(sum, addA:(int32_t)a withB:(int32_t)b) {\n    return @(a + b);\n}\n\n@end\n```\n\nCorresponding Java code:\n\n```java\n\n// load libdart_native.so\nDartNativePlugin.loadSo();\n\n@InterfaceEntry(name = \"MyFirstInterface\")\npublic class InterfaceDemo extends DartNativeInterface {\n\n    @InterfaceMethod(name = \"hello\")\n    public String hello(String str) {\n        return \"hello \" + str;\n    }\n\n    @InterfaceMethod(name = \"sum\")\n    public int sum(int a, int b) {\n        return a + b;\n    }\n}\n```\n\nNOTE: If your so path is custom, you need pass specific path.\n```Java\nDartNativePlugin.loadSoWithCustomPath(\"xxx/libdart_native.so\");\n```\nAnd before using DartNative in dart, first invoke ```dartNativeInitCustomSoPath()```. It will get path from channel.\n\n#### Native calls Dart\n\nDart code:\n\n```dart\ninterface.setMethodCallHandler('totalCost',\n        (double unitCost, int count, List list) async {\n    return {'totalCost: ${unitCost * count}': list};\n});\n```\n\nCorresponding Objective-C code:\n\n```objectivec\n[self invokeMethod:@\"totalCost\"\n         arguments:@[@0.123456789, @10, @[@\"testArray\"]]\n            result:^(id _Nullable result, NSError * _Nullable error) {\n    NSLog(@\"%@\", result);\n}];\n\n```\n\nCorresponding Java code:\n\n```java\ninvokeMethod(\"totalCost\", new Object[]{0.123456789, 10, Arrays.asList(\"hello\", \"world\")},\n             new DartNativeResult() {\n                @Override\n                public void onResult(@Nullable Object result) {\n                    Map retMap = (Map) result;\n                    // do something\n                }\n\n                @Override\n                public void error(@Nullable String errorMessage) {\n                    // do something\n                }\n              }\n);\n```\n\n#### Dart finalizer\n\n```dart\nfinal foo = Bar(); // A custom instance.\nunitTest.addFinalizer(() { // register a finalizer callback.\n  print('The instance of \\'foo\\' has been destroyed!'); // When `foo` is destroyed by GC, this line of code will be executed.\n});\n```\n\n#### Data types support\n\n| Dart | Objective-C | Swift | Java |\n| --- | --- | --- | --- |\n| null | nil | nil | null |\n| bool | BOOL | Bool | bool |\n| int | NSInteger | Int |int  |\n| double | double | Double | double |\n| String | NSString | String | String |\n| List | NSArray | Array | List, ArrayList |\n| Map | NSDictionary | Dictionary | Map, HashMap |\n| Set | NSSet | Set | Set, HashSet |\n| Function | Block | Closure | Promise |\n| Pointer | void * | UnsafeMutableRawPointer | - |\n| NativeByte | NSData | Data | DirectByteBuffer |\n| NativeObject | NSObject | NSObject | Object |\n\n### Advanced usage: Invoke methods dynamically\n\n- Step 1: Add ```dart_native``` to dependencies and ```build_runner``` to dev_dependencies.\n\n- Step 2: Generate Dart wrapper code with [@dartnative/codegen](https://www.npmjs.com/package/@dartnative/codegen) or write Dart code manually.\n\n- Step 3: Generate code for automatic type conversion using [dart_native_gen](https://pub.dev/packages/dart_native_gen) with the following steps (3.1-3.3):\n\n  + 3.1 Annotate a Dart wrapper class with `@native`.\n    ```dart\n    @native\n    class RuntimeSon extends RuntimeStub {\n      RuntimeSon([Class isa]) : super(Class('RuntimeSon'));\n      RuntimeSon.fromPointer(Pointer\u003cVoid\u003e ptr) : super.fromPointer(ptr);\n    }\n    ```\n  \n  + 3.2 Annotate your own entry (such as`main()`) with `@nativeRoot`.\n\n    ```dart\n    @nativeRoot\n    void main() {\n      runApp(App());\n    }\n    ```\n\n  + 3.3 Run  \n    ```bash \n    flutter packages pub run build_runner build --delete-conflicting-outputs \n    ```\n    to generate files into your source directory.\n\n    Note: we recommend running `clean` first:\n\n    ```bash\n    flutter packages pub run build_runner clean\n    ```\n\n- Step 4: Call autogenerated function in `\u003cgenerated-name\u003e.dn.dart` in 3.3. The function name is determined by `name` in `pubspec.yaml`.\n\n    ```dart\n    @nativeRoot\n    void main() {\n      // Function name is generated by name in pubspec.yaml.\n      runDartNativeExample(); \n      runApp(App());\n    }\n    ```\n\n- Step 5: Then you can write code. Here are some examples:\n\n  + 5.1 iOS:\n\n    Dart code (generated):\n\n    ```dart\n    // new Objective-C object.\n    RuntimeStub stub = RuntimeStub();\n\n    // Dart function will be converted to Objective-C block.\n    stub.fooBlock((NSObject a) {\n        print('hello block! ${a.toString()}');\n        return 101;\n    });\n\n    // support built-in structs.\n    CGRect rect = stub.fooCGRect(CGRect(4, 3, 2, 1));\n    print(rect);\n\n    ```\n    Corresponding Objective-C code:\n\n    ```objc\n    typedef int(^BarBlock)(NSObject *a);\n\n    @interface RuntimeStub\n\n    - (CGRect)fooCGRect:(CGRect)rect;\n    - (void)fooBlock:(BarBlock)block;\n\n    @end\n    ```\n\n    More iOS examples see: [ios_unit_test.dart](/dart_native/example/lib/ios/unit_test.dart)\n\n  + 5.2 Android:\n\n    Dart code (generated):\n    ```dart\n    // new Java object.\n    RuntimeStub stub = RuntimeStub();\n\n    // get java list.\n    List list = stub.getList([1, 2, 3, 4]);\n\n    // support interface.\n    stub.setDelegateListener(DelegateStub());\n\n    ```\n    Corresponding Java code:\n\n    ```java\n    public class RuntimeStub {\n\n        public List\u003cInteger\u003e getList(List\u003cInteger\u003e list) {\n            List\u003cInteger\u003e returnList = new ArrayList\u003c\u003e();\n            returnList.add(1);\n            returnList.add(2);\n            return returnList;\n        }\n\n        public void setDelegateListener(SampleDelegate delegate) {\n            delegate.callbackInt(1);\n        }\n    }\n    ```\n    More android examples see: [android_unit_test.dart](/dart_native/example/lib/android/unit_test.dart)\n\nNOTE: *If you use dart_native on macOS, you must use `use_frameworks!` in your Podfile.*\n\n## Documentation\n\n### Further reading\n\n- [告别 Flutter Channel，调用 Native API 仅需一行代码！](http://yulingtianxia.com/blog/2020/06/25/Codegen-for-DartNative/)\n- [如何实现一行命令自动生成 Flutter 插件](http://yulingtianxia.com/blog/2020/07/25/How-to-Implement-Codegen/)\n- [用 Dart 来写 Objective-C 代码](http://yulingtianxia.com/blog/2019/10/27/Write-Objective-C-Code-using-Dart/)\n- [谈谈 dart_native 混合编程引擎的设计](http://yulingtianxia.com/blog/2019/11/28/DartObjC-Design/)\n- [DartNative Memory Management: Object](http://yulingtianxia.com/blog/2019/12/26/DartObjC-Memory-Management-Object/)\n- [DartNative Memory Management: C++ Non-Object](http://yulingtianxia.com/blog/2020/01/31/DartNative-Memory-Management-Cpp-Non-Object/)\n- [DartNative Struct](http://yulingtianxia.com/blog/2020/02/24/DartNative-Struct/)\n- [在 Flutter 中玩转 Objective-C Block](http://yulingtianxia.com/blog/2020/03/28/Using-Objective-C-Block-in-Flutter/)\n- [Passing Out Parameter in DartNative](http://yulingtianxia.com/blog/2020/04/25/Passing-Out-Parameter-in-DartNative/)\n\n## FAQs\n\nQ: Failed to lookup symbol (dlsym(RTLD_DEFAULT, InitDartApiDL): symbol not found) on macOS archive.\n\nA: Select one solution:\n   1. Use dynamic library: Add `use_frameworks!` in Podfile.\n   2. Select Target Runner -\u003e Build Settings -\u003e Strip Style -\u003e change from \"All Symbols\" to \"Non-Global Symbols\"\n\n## Contribution\n\n- If you **need help** or you'd like to **ask a general question**, open an issue.\n- If you **found a bug**, open an issue.\n- If you **have a feature request**, open an issue.\n- If you **want to contribute**, submit a pull request.\n\n## License\n\nDartNative is available under the BSD 3-Clause License. See the LICENSE file for more info.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdart-native%2Fdart_native","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdart-native%2Fdart_native","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdart-native%2Fdart_native/lists"}