├── .gitignore
├── .idea
├── .gitignore
├── codeStyles
│ └── Project.xml
├── libraries
│ ├── Dart_SDK.xml
│ └── Flutter_Plugins.xml
├── misc.xml
├── modules.xml
├── runConfigurations
│ └── example_lib_main_dart.xml
├── vcs.xml
└── workspace.xml
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── android
├── .gitignore
├── CMakeLists.txt
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── settings.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── cpp
│ ├── native_callbacks_example.cpp
│ └── native_callbacks_example.h
│ └── kotlin
│ └── com
│ └── example
│ └── native_callbacks_example
│ └── NativeCallbacksExamplePlugin.kt
├── example
├── .gitignore
├── .metadata
├── README.md
├── android
│ ├── .gitignore
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── kotlin
│ │ │ │ └── com
│ │ │ │ │ └── example
│ │ │ │ │ └── native_callbacks_example_example
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── res
│ │ │ │ ├── drawable
│ │ │ │ └── launch_background.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ └── values
│ │ │ │ └── styles.xml
│ │ │ └── profile
│ │ │ └── AndroidManifest.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ └── settings.gradle
├── ios
│ ├── .gitignore
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Podfile
│ ├── Podfile.lock
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── Runner
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ └── README.md
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── Runner-Bridging-Header.h
├── lib
│ └── main.dart
├── pubspec.lock
└── pubspec.yaml
├── ios
├── .gitignore
├── Assets
│ └── .gitkeep
├── Classes
│ ├── NativeCallbacksExamplePlugin.h
│ ├── NativeCallbacksExamplePlugin.m
│ ├── Shared
│ │ ├── CallbackManager.cpp
│ │ └── CallbackManager.h
│ ├── SwiftNativeCallbacksExamplePlugin.swift
│ └── Utils.swift
└── native_callbacks_example.podspec
├── lib
└── native_callbacks_example.dart
├── native_callbacks_example.iml
├── pubspec.lock
└── pubspec.yaml
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .dart_tool/
3 |
4 | .packages
5 | .pub/
6 |
7 | build/
8 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Project exclude paths
2 | /.
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | xmlns:android
14 |
15 | ^$
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | xmlns:.*
25 |
26 | ^$
27 |
28 |
29 | BY_NAME
30 |
31 |
32 |
33 |
34 |
35 |
36 | .*:id
37 |
38 | http://schemas.android.com/apk/res/android
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | .*:name
48 |
49 | http://schemas.android.com/apk/res/android
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | name
59 |
60 | ^$
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | style
70 |
71 | ^$
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | .*
81 |
82 | ^$
83 |
84 |
85 | BY_NAME
86 |
87 |
88 |
89 |
90 |
91 |
92 | .*
93 |
94 | http://schemas.android.com/apk/res/android
95 |
96 |
97 | ANDROID_ATTRIBUTE_ORDER
98 |
99 |
100 |
101 |
102 |
103 |
104 | .*
105 |
106 | .*
107 |
108 |
109 | BY_NAME
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/.idea/libraries/Dart_SDK.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/libraries/Flutter_Plugins.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/example_lib_main_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | 1588357133803
79 |
80 |
81 | 1588357133803
82 |
83 |
84 |
85 |
86 |
87 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: e0c63cd35e15e407a80dc44281cc392535fcce25
8 | channel: dev
9 |
10 | project_type: plugin
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 0.0.1
2 |
3 | * TODO: Describe initial release.
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | TODO: Add your license here.
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # native_callbacks_example
2 |
3 | Example Flutter plugin that calls native code directly via FFI (no MethodChannels) and gets async callbacks.
4 |
5 | As of May 2020, you need to be on the dev channel of Flutter for this to work.
6 |
7 | ## Why
8 | The main motivation for this is to call directly into native NDK code on Android from Dart and get an async result. Also, on any platform, using FFI should involve less performance overhead.
9 |
10 | For example, say you were building a music app, and it needs to call Swift on the iOS side and C++ on the Android side for real-time audio operations. You wouldn't want to use PlatformChannels because of the added latency, and also because on Android you don't need to go through the JVM.
11 |
12 | ## How
13 |
14 | ### Plugin
15 | The Flutter plugin can be found at lib/native_callbacks_example.dart.
16 |
17 | Before doing anything else, you need to call `NativeCallbacksExample.doSetup()`. This gives the native code a reference to Dart_PostCObject, which it will use to send data back to Dart ports.
18 |
19 | It has two async methods:
20 | - `NativeCallbacksExample.methodA()`, which returns a `Future`
21 | - `NativeCallbacksExample.methodB()`, which returns a `Future>`
22 |
23 | Internally, the Dart methods use `singleResponseFuture` from the `isolate` library to create a Dart port and pass it to the native side on each function call, then await the next message received by that port.
24 |
25 | On Android, these methods will call the CPP files in /android/src/main/cpp/native_callbacks_example.cpp. (Note the changes in the C
26 |
27 | On iOS, it will call the Swift file at /ios/Classes/SwiftNativeCallbacksExamplePlugin.swift.
28 |
29 | For both platforms, the shared 'CallbackManager' is in /ios/Classes/Shared. It contains some C helpers to call Dart, and it holds the reference to Dart_PostCObject. (Note the line in the podspec file that adds a reference to these headers as USER_HEADER_SEARCH_PATHS.)
30 |
31 | ### Example app
32 | The example app can be found at example/lib/main.dart.
33 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | /.cxx
10 |
--------------------------------------------------------------------------------
/android/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.6)
2 |
3 | set (CALLBACK_MANAGER_DIR ../ios/Classes/Shared)
4 |
5 | add_library(
6 | android_native_callbacks_example
7 | SHARED
8 | ${CALLBACK_MANAGER_DIR}/CallbackManager.h
9 | ${CALLBACK_MANAGER_DIR}/CallbackManager.cpp
10 | ./src/main/cpp/native_callbacks_example.cpp)
11 |
12 | target_include_directories(android_native_callbacks_example PUBLIC ${CALLBACK_MANAGER_DIR})
13 |
14 | find_library( # Sets the name of the path variable.
15 | android-lib
16 |
17 | # Specifies the name of the NDK library that
18 | # you want CMake to locate.
19 | android )
20 |
21 | target_link_libraries(android_native_callbacks_example log)
22 | target_link_libraries(android_native_callbacks_example ${android-lib})
23 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | group 'com.example.native_callbacks_example'
2 | version '1.0-SNAPSHOT'
3 |
4 | buildscript {
5 | ext.kotlin_version = '1.3.50'
6 | repositories {
7 | google()
8 | jcenter()
9 | }
10 |
11 | dependencies {
12 | classpath 'com.android.tools.build:gradle:3.5.0'
13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14 | }
15 | }
16 |
17 | rootProject.allprojects {
18 | repositories {
19 | google()
20 | jcenter()
21 | }
22 | }
23 |
24 | apply plugin: 'com.android.library'
25 | apply plugin: 'kotlin-android'
26 |
27 | android {
28 | compileSdkVersion 28
29 |
30 | sourceSets {
31 | main.java.srcDirs += 'src/main/kotlin'
32 | }
33 | defaultConfig {
34 | minSdkVersion 16
35 | }
36 | lintOptions {
37 | disable 'InvalidPackage'
38 | }
39 | externalNativeBuild {
40 | cmake {
41 | path "CMakeLists.txt"
42 | }
43 | }
44 | }
45 |
46 | dependencies {
47 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
48 | }
49 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.enableR8=true
3 | android.useAndroidX=true
4 | android.enableJetifier=true
5 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
6 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'native_callbacks_example'
2 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/android/src/main/cpp/native_callbacks_example.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by M on 5/2/20.
3 | //
4 |
5 | #include "native_callbacks_example.h"
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 |
14 | void method_a(Dart_Port callbackPort) {
15 | __android_log_print(ANDROID_LOG_INFO, "NATIVE_CALLBACKS_EXAMPLE", "Started method A");
16 |
17 | std::thread t([=]() {
18 | std::this_thread::sleep_for(std::chrono::seconds(1));
19 |
20 | int32_t value = 123;
21 |
22 | callbackToDartInt32(callbackPort, value);
23 | __android_log_print(ANDROID_LOG_INFO, "NATIVE_CALLBACKS_EXAMPLE", "Finished method A");
24 | });
25 |
26 | t.detach();
27 | };
28 |
29 | void method_b(Dart_Port callbackPort) {
30 | __android_log_print(ANDROID_LOG_INFO, "NATIVE_CALLBACKS_EXAMPLE", "Started method B");
31 |
32 | std::thread t([=](){
33 | std::this_thread::sleep_for(std::chrono::seconds(2));
34 |
35 | const int length = 2;
36 | char** values = new char* [length];
37 |
38 | values[0] = "abc";
39 | values[1] = "def";
40 |
41 | callbackToDartStrArray(callbackPort, length, values);
42 |
43 | delete []values;
44 | __android_log_print(ANDROID_LOG_INFO, "NATIVE_CALLBACKS_EXAMPLE", "Finished method B");
45 | });
46 |
47 | t.detach();
48 | };
49 |
--------------------------------------------------------------------------------
/android/src/main/cpp/native_callbacks_example.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by M on 5/2/20.
3 | //
4 |
5 | #ifndef NATIVE_CALLBACKS_EXAMPLE_NATIVE_CALLBACKS_EXAMPLE_H
6 | #define NATIVE_CALLBACKS_EXAMPLE_NATIVE_CALLBACKS_EXAMPLE_H
7 | #include
8 |
9 | #ifdef __cplusplus
10 | extern "C" {
11 | #endif
12 | void method_a(Dart_Port callbackPort);
13 | void method_b(Dart_Port callbackPort);
14 | #ifdef __cplusplus
15 | }
16 | #endif
17 | #endif //NATIVE_CALLBACKS_EXAMPLE_NATIVE_CALLBACKS_EXAMPLE_H
18 |
--------------------------------------------------------------------------------
/android/src/main/kotlin/com/example/native_callbacks_example/NativeCallbacksExamplePlugin.kt:
--------------------------------------------------------------------------------
1 | package com.example.native_callbacks_example
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | import io.flutter.embedding.engine.plugins.FlutterPlugin
6 | import io.flutter.plugin.common.MethodCall
7 | import io.flutter.plugin.common.MethodChannel
8 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler
9 | import io.flutter.plugin.common.MethodChannel.Result
10 | import io.flutter.plugin.common.PluginRegistry.Registrar
11 |
12 | /** NativeCallbacksExamplePlugin */
13 | public class NativeCallbacksExamplePlugin: FlutterPlugin, MethodCallHandler {
14 | /// The MethodChannel that will the communication between Flutter and native Android
15 | ///
16 | /// This local reference serves to register the plugin with the Flutter Engine and unregister it
17 | /// when the Flutter Engine is detached from the Activity
18 | private lateinit var channel : MethodChannel
19 |
20 | override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
21 | channel = MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "native_callbacks_example")
22 | channel.setMethodCallHandler(this);
23 | }
24 |
25 | // This static function is optional and equivalent to onAttachedToEngine. It supports the old
26 | // pre-Flutter-1.12 Android projects. You are encouraged to continue supporting
27 | // plugin registration via this function while apps migrate to use the new Android APIs
28 | // post-flutter-1.12 via https://flutter.dev/go/android-project-migration.
29 | //
30 | // It is encouraged to share logic between onAttachedToEngine and registerWith to keep
31 | // them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called
32 | // depending on the user's project. onAttachedToEngine or registerWith must both be defined
33 | // in the same class.
34 | companion object {
35 | @JvmStatic
36 | fun registerWith(registrar: Registrar) {
37 | val channel = MethodChannel(registrar.messenger(), "native_callbacks_example")
38 | channel.setMethodCallHandler(NativeCallbacksExamplePlugin())
39 | }
40 | }
41 |
42 | override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
43 | if (call.method == "getPlatformVersion") {
44 | result.success("Android ${android.os.Build.VERSION.RELEASE}")
45 | } else {
46 | result.notImplemented()
47 | }
48 | }
49 |
50 | override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
51 | channel.setMethodCallHandler(null)
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | **/ios/Flutter/.last_build_id
26 | .dart_tool/
27 | .flutter-plugins
28 | .flutter-plugins-dependencies
29 | .packages
30 | .pub-cache/
31 | .pub/
32 | /build/
33 |
34 | # Web related
35 | lib/generated_plugin_registrant.dart
36 |
37 | # Symbolication related
38 | app.*.symbols
39 |
40 | # Obfuscation related
41 | app.*.map.json
42 |
43 | # Exceptions to above rules.
44 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
45 |
--------------------------------------------------------------------------------
/example/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: e0c63cd35e15e407a80dc44281cc392535fcce25
8 | channel: dev
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # native_callbacks_example_example
2 |
3 | Demonstrates how to use the native_callbacks_example plugin.
4 |
5 | ## Getting Started
6 |
7 | This project is a starting point for a Flutter application.
8 |
9 | A few resources to get you started if this is your first Flutter project:
10 |
11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
13 |
14 | For help getting started with Flutter, view our
15 | [online documentation](https://flutter.dev/docs), which offers tutorials,
16 | samples, guidance on mobile development, and a full API reference.
17 |
--------------------------------------------------------------------------------
/example/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
--------------------------------------------------------------------------------
/example/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion 28
30 |
31 | sourceSets {
32 | main.java.srcDirs += 'src/main/kotlin'
33 | }
34 |
35 | lintOptions {
36 | disable 'InvalidPackage'
37 | }
38 |
39 | defaultConfig {
40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
41 | applicationId "com.example.native_callbacks_example_example"
42 | minSdkVersion 16
43 | targetSdkVersion 28
44 | versionCode flutterVersionCode.toInteger()
45 | versionName flutterVersionName
46 | }
47 |
48 | buildTypes {
49 | release {
50 | // TODO: Add your own signing config for the release build.
51 | // Signing with the debug keys for now, so `flutter run --release` works.
52 | signingConfig signingConfigs.debug
53 | }
54 | }
55 | }
56 |
57 | flutter {
58 | source '../..'
59 | }
60 |
61 | dependencies {
62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
63 | }
64 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
8 |
12 |
19 |
23 |
27 |
32 |
36 |
37 |
38 |
39 |
40 |
41 |
43 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/example/android/app/src/main/kotlin/com/example/native_callbacks_example_example/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.native_callbacks_example_example
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/example/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.5.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | jcenter()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.enableR8=true
3 | android.useAndroidX=true
4 | android.enableJetifier=true
5 |
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
7 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | // Copyright 2014 The Flutter Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | include ':app'
6 |
7 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
8 | def properties = new Properties()
9 |
10 | assert localPropertiesFile.exists()
11 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
12 |
13 | def flutterSdkPath = properties.getProperty("flutter.sdk")
14 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
15 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
16 |
--------------------------------------------------------------------------------
/example/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/app.flx
22 | Flutter/app.zip
23 | Flutter/flutter_assets/
24 | Flutter/flutter_export_environment.sh
25 | ServiceDefinitions.json
26 | Runner/GeneratedPluginRegistrant.*
27 |
28 | # Exceptions to above rules.
29 | !default.mode1v3
30 | !default.mode2v3
31 | !default.pbxuser
32 | !default.perspectivev3
33 |
--------------------------------------------------------------------------------
/example/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def parse_KV_file(file, separator='=')
14 | file_abs_path = File.expand_path(file)
15 | if !File.exists? file_abs_path
16 | return [];
17 | end
18 | generated_key_values = {}
19 | skip_line_start_symbols = ["#", "/"]
20 | File.foreach(file_abs_path) do |line|
21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
22 | plugin = line.split(pattern=separator)
23 | if plugin.length == 2
24 | podname = plugin[0].strip()
25 | path = plugin[1].strip()
26 | podpath = File.expand_path("#{path}", file_abs_path)
27 | generated_key_values[podname] = podpath
28 | else
29 | puts "Invalid plugin specification: #{line}"
30 | end
31 | end
32 | generated_key_values
33 | end
34 |
35 | target 'Runner' do
36 | use_frameworks!
37 | use_modular_headers!
38 |
39 | # Flutter Pod
40 |
41 | copied_flutter_dir = File.join(__dir__, 'Flutter')
42 | copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
43 | copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
44 | unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
45 | # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
46 | # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
47 | # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
48 |
49 | generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
50 | unless File.exist?(generated_xcode_build_settings_path)
51 | raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
52 | end
53 | generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
54 | cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
55 |
56 | unless File.exist?(copied_framework_path)
57 | FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
58 | end
59 | unless File.exist?(copied_podspec_path)
60 | FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
61 | end
62 | end
63 |
64 | # Keep pod path relative so it can be checked into Podfile.lock.
65 | pod 'Flutter', :path => 'Flutter'
66 |
67 | # Plugin Pods
68 |
69 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
70 | # referring to absolute paths on developers' machines.
71 | system('rm -rf .symlinks')
72 | system('mkdir -p .symlinks/plugins')
73 | plugin_pods = parse_KV_file('../.flutter-plugins')
74 | plugin_pods.each do |name, path|
75 | symlink = File.join('.symlinks', 'plugins', name)
76 | File.symlink(path, symlink)
77 | pod name, :path => File.join(symlink, 'ios')
78 | end
79 | end
80 |
81 | post_install do |installer|
82 | installer.pods_project.targets.each do |target|
83 | target.build_configurations.each do |config|
84 | config.build_settings['ENABLE_BITCODE'] = 'NO'
85 | end
86 | end
87 | end
88 |
--------------------------------------------------------------------------------
/example/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Flutter (1.0.0)
3 | - native_callbacks_example (0.0.1):
4 | - Flutter
5 |
6 | DEPENDENCIES:
7 | - Flutter (from `Flutter`)
8 | - native_callbacks_example (from `.symlinks/plugins/native_callbacks_example/ios`)
9 |
10 | EXTERNAL SOURCES:
11 | Flutter:
12 | :path: Flutter
13 | native_callbacks_example:
14 | :path: ".symlinks/plugins/native_callbacks_example/ios"
15 |
16 | SPEC CHECKSUMS:
17 | Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
18 | native_callbacks_example: 700d2add47c219c4f3008ac5e5a224133c850142
19 |
20 | PODFILE CHECKSUM: c34e2287a9ccaa606aeceab922830efb9a6ff69a
21 |
22 | COCOAPODS: 1.9.1
23 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 15AB07FABCE231079F49016A /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6DBC21C62E7AD9B3C8B0878 /* Pods_Runner.framework */; };
12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
13 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
14 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
15 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
16 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXCopyFilesBuildPhase section */
20 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
21 | isa = PBXCopyFilesBuildPhase;
22 | buildActionMask = 2147483647;
23 | dstPath = "";
24 | dstSubfolderSpec = 10;
25 | files = (
26 | );
27 | name = "Embed Frameworks";
28 | runOnlyForDeploymentPostprocessing = 0;
29 | };
30 | /* End PBXCopyFilesBuildPhase section */
31 |
32 | /* Begin PBXFileReference section */
33 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
34 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
35 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
36 | 4EFFEDD5D361C5B818B53EEB /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; };
37 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
38 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
39 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
40 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
41 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
42 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
43 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
44 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
45 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
46 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
47 | 9BBD7643D9E2559012B554ED /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
48 | B6DBC21C62E7AD9B3C8B0878 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
49 | DCBDE3B722088982C2C4EAA2 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; };
50 | /* End PBXFileReference section */
51 |
52 | /* Begin PBXFrameworksBuildPhase section */
53 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
54 | isa = PBXFrameworksBuildPhase;
55 | buildActionMask = 2147483647;
56 | files = (
57 | 15AB07FABCE231079F49016A /* Pods_Runner.framework in Frameworks */,
58 | );
59 | runOnlyForDeploymentPostprocessing = 0;
60 | };
61 | /* End PBXFrameworksBuildPhase section */
62 |
63 | /* Begin PBXGroup section */
64 | 8462222896E88527CF82325C /* Frameworks */ = {
65 | isa = PBXGroup;
66 | children = (
67 | B6DBC21C62E7AD9B3C8B0878 /* Pods_Runner.framework */,
68 | );
69 | name = Frameworks;
70 | sourceTree = "";
71 | };
72 | 9740EEB11CF90186004384FC /* Flutter */ = {
73 | isa = PBXGroup;
74 | children = (
75 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
76 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
77 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
78 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
79 | );
80 | name = Flutter;
81 | sourceTree = "";
82 | };
83 | 97C146E51CF9000F007C117D = {
84 | isa = PBXGroup;
85 | children = (
86 | 9740EEB11CF90186004384FC /* Flutter */,
87 | 97C146F01CF9000F007C117D /* Runner */,
88 | 97C146EF1CF9000F007C117D /* Products */,
89 | A4ECC274D9DC8D27CE5FF8B2 /* Pods */,
90 | 8462222896E88527CF82325C /* Frameworks */,
91 | );
92 | sourceTree = "";
93 | };
94 | 97C146EF1CF9000F007C117D /* Products */ = {
95 | isa = PBXGroup;
96 | children = (
97 | 97C146EE1CF9000F007C117D /* Runner.app */,
98 | );
99 | name = Products;
100 | sourceTree = "";
101 | };
102 | 97C146F01CF9000F007C117D /* Runner */ = {
103 | isa = PBXGroup;
104 | children = (
105 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
106 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
107 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
108 | 97C147021CF9000F007C117D /* Info.plist */,
109 | 97C146F11CF9000F007C117D /* Supporting Files */,
110 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
111 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
112 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
113 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
114 | );
115 | path = Runner;
116 | sourceTree = "";
117 | };
118 | 97C146F11CF9000F007C117D /* Supporting Files */ = {
119 | isa = PBXGroup;
120 | children = (
121 | );
122 | name = "Supporting Files";
123 | sourceTree = "";
124 | };
125 | A4ECC274D9DC8D27CE5FF8B2 /* Pods */ = {
126 | isa = PBXGroup;
127 | children = (
128 | 9BBD7643D9E2559012B554ED /* Pods-Runner.debug.xcconfig */,
129 | 4EFFEDD5D361C5B818B53EEB /* Pods-Runner.release.xcconfig */,
130 | DCBDE3B722088982C2C4EAA2 /* Pods-Runner.profile.xcconfig */,
131 | );
132 | name = Pods;
133 | path = Pods;
134 | sourceTree = "";
135 | };
136 | /* End PBXGroup section */
137 |
138 | /* Begin PBXNativeTarget section */
139 | 97C146ED1CF9000F007C117D /* Runner */ = {
140 | isa = PBXNativeTarget;
141 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
142 | buildPhases = (
143 | 6133881827B1BFCC2DEC07D1 /* [CP] Check Pods Manifest.lock */,
144 | 9740EEB61CF901F6004384FC /* Run Script */,
145 | 97C146EA1CF9000F007C117D /* Sources */,
146 | 97C146EB1CF9000F007C117D /* Frameworks */,
147 | 97C146EC1CF9000F007C117D /* Resources */,
148 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
149 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
150 | 164A91E2B223039700B1A518 /* [CP] Embed Pods Frameworks */,
151 | );
152 | buildRules = (
153 | );
154 | dependencies = (
155 | );
156 | name = Runner;
157 | productName = Runner;
158 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
159 | productType = "com.apple.product-type.application";
160 | };
161 | /* End PBXNativeTarget section */
162 |
163 | /* Begin PBXProject section */
164 | 97C146E61CF9000F007C117D /* Project object */ = {
165 | isa = PBXProject;
166 | attributes = {
167 | LastUpgradeCheck = 1020;
168 | ORGANIZATIONNAME = "";
169 | TargetAttributes = {
170 | 97C146ED1CF9000F007C117D = {
171 | CreatedOnToolsVersion = 7.3.1;
172 | LastSwiftMigration = 1100;
173 | };
174 | };
175 | };
176 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
177 | compatibilityVersion = "Xcode 9.3";
178 | developmentRegion = en;
179 | hasScannedForEncodings = 0;
180 | knownRegions = (
181 | en,
182 | Base,
183 | );
184 | mainGroup = 97C146E51CF9000F007C117D;
185 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
186 | projectDirPath = "";
187 | projectRoot = "";
188 | targets = (
189 | 97C146ED1CF9000F007C117D /* Runner */,
190 | );
191 | };
192 | /* End PBXProject section */
193 |
194 | /* Begin PBXResourcesBuildPhase section */
195 | 97C146EC1CF9000F007C117D /* Resources */ = {
196 | isa = PBXResourcesBuildPhase;
197 | buildActionMask = 2147483647;
198 | files = (
199 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
200 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
201 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
202 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
203 | );
204 | runOnlyForDeploymentPostprocessing = 0;
205 | };
206 | /* End PBXResourcesBuildPhase section */
207 |
208 | /* Begin PBXShellScriptBuildPhase section */
209 | 164A91E2B223039700B1A518 /* [CP] Embed Pods Frameworks */ = {
210 | isa = PBXShellScriptBuildPhase;
211 | buildActionMask = 2147483647;
212 | files = (
213 | );
214 | inputPaths = (
215 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
216 | "${PODS_ROOT}/../Flutter/Flutter.framework",
217 | "${BUILT_PRODUCTS_DIR}/native_callbacks_example/native_callbacks_example.framework",
218 | );
219 | name = "[CP] Embed Pods Frameworks";
220 | outputPaths = (
221 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
222 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/native_callbacks_example.framework",
223 | );
224 | runOnlyForDeploymentPostprocessing = 0;
225 | shellPath = /bin/sh;
226 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
227 | showEnvVarsInLog = 0;
228 | };
229 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
230 | isa = PBXShellScriptBuildPhase;
231 | buildActionMask = 2147483647;
232 | files = (
233 | );
234 | inputPaths = (
235 | );
236 | name = "Thin Binary";
237 | outputPaths = (
238 | );
239 | runOnlyForDeploymentPostprocessing = 0;
240 | shellPath = /bin/sh;
241 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
242 | };
243 | 6133881827B1BFCC2DEC07D1 /* [CP] Check Pods Manifest.lock */ = {
244 | isa = PBXShellScriptBuildPhase;
245 | buildActionMask = 2147483647;
246 | files = (
247 | );
248 | inputFileListPaths = (
249 | );
250 | inputPaths = (
251 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
252 | "${PODS_ROOT}/Manifest.lock",
253 | );
254 | name = "[CP] Check Pods Manifest.lock";
255 | outputFileListPaths = (
256 | );
257 | outputPaths = (
258 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
259 | );
260 | runOnlyForDeploymentPostprocessing = 0;
261 | shellPath = /bin/sh;
262 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
263 | showEnvVarsInLog = 0;
264 | };
265 | 9740EEB61CF901F6004384FC /* Run Script */ = {
266 | isa = PBXShellScriptBuildPhase;
267 | buildActionMask = 2147483647;
268 | files = (
269 | );
270 | inputPaths = (
271 | );
272 | name = "Run Script";
273 | outputPaths = (
274 | );
275 | runOnlyForDeploymentPostprocessing = 0;
276 | shellPath = /bin/sh;
277 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
278 | };
279 | /* End PBXShellScriptBuildPhase section */
280 |
281 | /* Begin PBXSourcesBuildPhase section */
282 | 97C146EA1CF9000F007C117D /* Sources */ = {
283 | isa = PBXSourcesBuildPhase;
284 | buildActionMask = 2147483647;
285 | files = (
286 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
287 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
288 | );
289 | runOnlyForDeploymentPostprocessing = 0;
290 | };
291 | /* End PBXSourcesBuildPhase section */
292 |
293 | /* Begin PBXVariantGroup section */
294 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
295 | isa = PBXVariantGroup;
296 | children = (
297 | 97C146FB1CF9000F007C117D /* Base */,
298 | );
299 | name = Main.storyboard;
300 | sourceTree = "";
301 | };
302 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
303 | isa = PBXVariantGroup;
304 | children = (
305 | 97C147001CF9000F007C117D /* Base */,
306 | );
307 | name = LaunchScreen.storyboard;
308 | sourceTree = "";
309 | };
310 | /* End PBXVariantGroup section */
311 |
312 | /* Begin XCBuildConfiguration section */
313 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
314 | isa = XCBuildConfiguration;
315 | buildSettings = {
316 | ALWAYS_SEARCH_USER_PATHS = NO;
317 | CLANG_ANALYZER_NONNULL = YES;
318 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
319 | CLANG_CXX_LIBRARY = "libc++";
320 | CLANG_ENABLE_MODULES = YES;
321 | CLANG_ENABLE_OBJC_ARC = YES;
322 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
323 | CLANG_WARN_BOOL_CONVERSION = YES;
324 | CLANG_WARN_COMMA = YES;
325 | CLANG_WARN_CONSTANT_CONVERSION = YES;
326 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
327 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
328 | CLANG_WARN_EMPTY_BODY = YES;
329 | CLANG_WARN_ENUM_CONVERSION = YES;
330 | CLANG_WARN_INFINITE_RECURSION = YES;
331 | CLANG_WARN_INT_CONVERSION = YES;
332 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
333 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
334 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
335 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
336 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
337 | CLANG_WARN_STRICT_PROTOTYPES = YES;
338 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
339 | CLANG_WARN_UNREACHABLE_CODE = YES;
340 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
341 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
342 | COPY_PHASE_STRIP = NO;
343 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
344 | ENABLE_NS_ASSERTIONS = NO;
345 | ENABLE_STRICT_OBJC_MSGSEND = YES;
346 | GCC_C_LANGUAGE_STANDARD = gnu99;
347 | GCC_NO_COMMON_BLOCKS = YES;
348 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
349 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
350 | GCC_WARN_UNDECLARED_SELECTOR = YES;
351 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
352 | GCC_WARN_UNUSED_FUNCTION = YES;
353 | GCC_WARN_UNUSED_VARIABLE = YES;
354 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
355 | MTL_ENABLE_DEBUG_INFO = NO;
356 | SDKROOT = iphoneos;
357 | SUPPORTED_PLATFORMS = iphoneos;
358 | TARGETED_DEVICE_FAMILY = "1,2";
359 | VALIDATE_PRODUCT = YES;
360 | };
361 | name = Profile;
362 | };
363 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
364 | isa = XCBuildConfiguration;
365 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
366 | buildSettings = {
367 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
368 | CLANG_ENABLE_MODULES = YES;
369 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
370 | ENABLE_BITCODE = NO;
371 | FRAMEWORK_SEARCH_PATHS = (
372 | "$(inherited)",
373 | "$(PROJECT_DIR)/Flutter",
374 | );
375 | INFOPLIST_FILE = Runner/Info.plist;
376 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
377 | LIBRARY_SEARCH_PATHS = (
378 | "$(inherited)",
379 | "$(PROJECT_DIR)/Flutter",
380 | );
381 | PRODUCT_BUNDLE_IDENTIFIER = com.example.nativeCallbacksExampleExample;
382 | PRODUCT_NAME = "$(TARGET_NAME)";
383 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
384 | SWIFT_VERSION = 5.0;
385 | VERSIONING_SYSTEM = "apple-generic";
386 | };
387 | name = Profile;
388 | };
389 | 97C147031CF9000F007C117D /* Debug */ = {
390 | isa = XCBuildConfiguration;
391 | buildSettings = {
392 | ALWAYS_SEARCH_USER_PATHS = NO;
393 | CLANG_ANALYZER_NONNULL = YES;
394 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
395 | CLANG_CXX_LIBRARY = "libc++";
396 | CLANG_ENABLE_MODULES = YES;
397 | CLANG_ENABLE_OBJC_ARC = YES;
398 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
399 | CLANG_WARN_BOOL_CONVERSION = YES;
400 | CLANG_WARN_COMMA = YES;
401 | CLANG_WARN_CONSTANT_CONVERSION = YES;
402 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
403 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
404 | CLANG_WARN_EMPTY_BODY = YES;
405 | CLANG_WARN_ENUM_CONVERSION = YES;
406 | CLANG_WARN_INFINITE_RECURSION = YES;
407 | CLANG_WARN_INT_CONVERSION = YES;
408 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
409 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
410 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
411 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
412 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
413 | CLANG_WARN_STRICT_PROTOTYPES = YES;
414 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
415 | CLANG_WARN_UNREACHABLE_CODE = YES;
416 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
417 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
418 | COPY_PHASE_STRIP = NO;
419 | DEBUG_INFORMATION_FORMAT = dwarf;
420 | ENABLE_STRICT_OBJC_MSGSEND = YES;
421 | ENABLE_TESTABILITY = YES;
422 | GCC_C_LANGUAGE_STANDARD = gnu99;
423 | GCC_DYNAMIC_NO_PIC = NO;
424 | GCC_NO_COMMON_BLOCKS = YES;
425 | GCC_OPTIMIZATION_LEVEL = 0;
426 | GCC_PREPROCESSOR_DEFINITIONS = (
427 | "DEBUG=1",
428 | "$(inherited)",
429 | );
430 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
431 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
432 | GCC_WARN_UNDECLARED_SELECTOR = YES;
433 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
434 | GCC_WARN_UNUSED_FUNCTION = YES;
435 | GCC_WARN_UNUSED_VARIABLE = YES;
436 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
437 | MTL_ENABLE_DEBUG_INFO = YES;
438 | ONLY_ACTIVE_ARCH = YES;
439 | SDKROOT = iphoneos;
440 | TARGETED_DEVICE_FAMILY = "1,2";
441 | };
442 | name = Debug;
443 | };
444 | 97C147041CF9000F007C117D /* Release */ = {
445 | isa = XCBuildConfiguration;
446 | buildSettings = {
447 | ALWAYS_SEARCH_USER_PATHS = NO;
448 | CLANG_ANALYZER_NONNULL = YES;
449 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
450 | CLANG_CXX_LIBRARY = "libc++";
451 | CLANG_ENABLE_MODULES = YES;
452 | CLANG_ENABLE_OBJC_ARC = YES;
453 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
454 | CLANG_WARN_BOOL_CONVERSION = YES;
455 | CLANG_WARN_COMMA = YES;
456 | CLANG_WARN_CONSTANT_CONVERSION = YES;
457 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
458 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
459 | CLANG_WARN_EMPTY_BODY = YES;
460 | CLANG_WARN_ENUM_CONVERSION = YES;
461 | CLANG_WARN_INFINITE_RECURSION = YES;
462 | CLANG_WARN_INT_CONVERSION = YES;
463 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
464 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
465 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
466 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
467 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
468 | CLANG_WARN_STRICT_PROTOTYPES = YES;
469 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
470 | CLANG_WARN_UNREACHABLE_CODE = YES;
471 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
472 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
473 | COPY_PHASE_STRIP = NO;
474 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
475 | ENABLE_NS_ASSERTIONS = NO;
476 | ENABLE_STRICT_OBJC_MSGSEND = YES;
477 | GCC_C_LANGUAGE_STANDARD = gnu99;
478 | GCC_NO_COMMON_BLOCKS = YES;
479 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
480 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
481 | GCC_WARN_UNDECLARED_SELECTOR = YES;
482 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
483 | GCC_WARN_UNUSED_FUNCTION = YES;
484 | GCC_WARN_UNUSED_VARIABLE = YES;
485 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
486 | MTL_ENABLE_DEBUG_INFO = NO;
487 | SDKROOT = iphoneos;
488 | SUPPORTED_PLATFORMS = iphoneos;
489 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
490 | TARGETED_DEVICE_FAMILY = "1,2";
491 | VALIDATE_PRODUCT = YES;
492 | };
493 | name = Release;
494 | };
495 | 97C147061CF9000F007C117D /* Debug */ = {
496 | isa = XCBuildConfiguration;
497 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
498 | buildSettings = {
499 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
500 | CLANG_ENABLE_MODULES = YES;
501 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
502 | ENABLE_BITCODE = NO;
503 | FRAMEWORK_SEARCH_PATHS = (
504 | "$(inherited)",
505 | "$(PROJECT_DIR)/Flutter",
506 | );
507 | INFOPLIST_FILE = Runner/Info.plist;
508 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
509 | LIBRARY_SEARCH_PATHS = (
510 | "$(inherited)",
511 | "$(PROJECT_DIR)/Flutter",
512 | );
513 | PRODUCT_BUNDLE_IDENTIFIER = com.example.nativeCallbacksExampleExample;
514 | PRODUCT_NAME = "$(TARGET_NAME)";
515 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
516 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
517 | SWIFT_VERSION = 5.0;
518 | VERSIONING_SYSTEM = "apple-generic";
519 | };
520 | name = Debug;
521 | };
522 | 97C147071CF9000F007C117D /* Release */ = {
523 | isa = XCBuildConfiguration;
524 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
525 | buildSettings = {
526 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
527 | CLANG_ENABLE_MODULES = YES;
528 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
529 | ENABLE_BITCODE = NO;
530 | FRAMEWORK_SEARCH_PATHS = (
531 | "$(inherited)",
532 | "$(PROJECT_DIR)/Flutter",
533 | );
534 | INFOPLIST_FILE = Runner/Info.plist;
535 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
536 | LIBRARY_SEARCH_PATHS = (
537 | "$(inherited)",
538 | "$(PROJECT_DIR)/Flutter",
539 | );
540 | PRODUCT_BUNDLE_IDENTIFIER = com.example.nativeCallbacksExampleExample;
541 | PRODUCT_NAME = "$(TARGET_NAME)";
542 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
543 | SWIFT_VERSION = 5.0;
544 | VERSIONING_SYSTEM = "apple-generic";
545 | };
546 | name = Release;
547 | };
548 | /* End XCBuildConfiguration section */
549 |
550 | /* Begin XCConfigurationList section */
551 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
552 | isa = XCConfigurationList;
553 | buildConfigurations = (
554 | 97C147031CF9000F007C117D /* Debug */,
555 | 97C147041CF9000F007C117D /* Release */,
556 | 249021D3217E4FDB00AE95B9 /* Profile */,
557 | );
558 | defaultConfigurationIsVisible = 0;
559 | defaultConfigurationName = Release;
560 | };
561 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
562 | isa = XCConfigurationList;
563 | buildConfigurations = (
564 | 97C147061CF9000F007C117D /* Debug */,
565 | 97C147071CF9000F007C117D /* Release */,
566 | 249021D4217E4FDB00AE95B9 /* Profile */,
567 | );
568 | defaultConfigurationIsVisible = 0;
569 | defaultConfigurationName = Release;
570 | };
571 | /* End XCConfigurationList section */
572 | };
573 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
574 | }
575 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | native_callbacks_example_example
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/example/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/example/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'dart:async';
3 |
4 | import 'package:async/async.dart';
5 | import 'package:native_callbacks_example/native_callbacks_example.dart';
6 |
7 | void main() {
8 | runApp(MyApp());
9 | }
10 |
11 | class MyApp extends StatefulWidget {
12 | @override
13 | _MyAppState createState() => _MyAppState();
14 | }
15 |
16 | class _MyAppState extends State {
17 | CancelableOperation methodAOperation;
18 | CancelableOperation> methodBOperation;
19 | int methodAResult;
20 | List methodBResult;
21 |
22 | @override
23 | void initState() {
24 | super.initState();
25 | NativeCallbacksExample.doSetup();
26 | getNativeData();
27 | }
28 |
29 | Future getNativeData() async {
30 | methodAOperation?.cancel();
31 | methodBOperation?.cancel();
32 |
33 | setState(() {
34 | methodAResult = null;
35 | methodBResult = null;
36 | });
37 |
38 | methodAOperation = CancelableOperation.fromFuture(NativeCallbacksExample.methodA());
39 | methodAOperation
40 | .value
41 | .then((_methodAResult) {
42 | setState(() {
43 | methodAResult = _methodAResult;
44 | });
45 | });
46 |
47 | methodBOperation = CancelableOperation.fromFuture(NativeCallbacksExample.methodB());
48 | methodBOperation
49 | .value
50 | .then((_methodBResult) {
51 | setState(() {
52 | methodBResult = _methodBResult;
53 | });
54 | });
55 | }
56 |
57 | @override
58 | Widget build(BuildContext context) {
59 | return MaterialApp(
60 | home: Scaffold(
61 | appBar: AppBar(
62 | title: const Text('Plugin example app'),
63 | ),
64 | body: Column(
65 | mainAxisAlignment: MainAxisAlignment.center,
66 | children: [
67 | Center(child: Text('Method A result: $methodAResult')),
68 | Center(child: Text('Method B result: ${methodBResult?.join()}')),
69 | RaisedButton(
70 | onPressed: getNativeData,
71 | child: Text('Call native methods'),
72 | ),
73 | ],
74 | ),
75 | ),
76 | );
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/example/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: "direct main"
6 | description:
7 | name: async
8 | url: "https://pub.dartlang.org"
9 | source: hosted
10 | version: "2.4.1"
11 | collection:
12 | dependency: transitive
13 | description:
14 | name: collection
15 | url: "https://pub.dartlang.org"
16 | source: hosted
17 | version: "1.14.12"
18 | cupertino_icons:
19 | dependency: "direct main"
20 | description:
21 | name: cupertino_icons
22 | url: "https://pub.dartlang.org"
23 | source: hosted
24 | version: "0.1.3"
25 | flutter:
26 | dependency: "direct main"
27 | description: flutter
28 | source: sdk
29 | version: "0.0.0"
30 | isolate:
31 | dependency: transitive
32 | description:
33 | name: isolate
34 | url: "https://pub.dartlang.org"
35 | source: hosted
36 | version: "2.0.3"
37 | meta:
38 | dependency: transitive
39 | description:
40 | name: meta
41 | url: "https://pub.dartlang.org"
42 | source: hosted
43 | version: "1.1.8"
44 | native_callbacks_example:
45 | dependency: "direct main"
46 | description:
47 | path: ".."
48 | relative: true
49 | source: path
50 | version: "0.0.1"
51 | sky_engine:
52 | dependency: transitive
53 | description: flutter
54 | source: sdk
55 | version: "0.0.99"
56 | typed_data:
57 | dependency: transitive
58 | description:
59 | name: typed_data
60 | url: "https://pub.dartlang.org"
61 | source: hosted
62 | version: "1.1.6"
63 | vector_math:
64 | dependency: transitive
65 | description:
66 | name: vector_math
67 | url: "https://pub.dartlang.org"
68 | source: hosted
69 | version: "2.0.8"
70 | sdks:
71 | dart: ">=2.7.0 <3.0.0"
72 | flutter: ">=1.18.0-8.0.pre"
73 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: native_callbacks_example_example
2 | description: Demonstrates how to use the native_callbacks_example plugin.
3 |
4 | # The following line prevents the package from being accidentally published to
5 | # pub.dev using `pub publish`. This is preferred for private packages.
6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev
7 |
8 | environment:
9 | sdk: ">=2.7.0 <3.0.0"
10 |
11 | dependencies:
12 | flutter:
13 | sdk: flutter
14 | async: "^2.4.1"
15 |
16 | native_callbacks_example:
17 | # When depending on this package from a real application you should use:
18 | # native_callbacks_example: ^x.y.z
19 | # See https://dart.dev/tools/pub/dependencies#version-constraints
20 | # The example app is bundled with the plugin so we use a path dependency on
21 | # the parent directory to use the current plugin's version.
22 | path: ../
23 |
24 | # The following adds the Cupertino Icons font to your application.
25 | # Use with the CupertinoIcons class for iOS style icons.
26 | cupertino_icons: ^0.1.3
27 |
28 | # For information on the generic Dart part of this file, see the
29 | # following page: https://dart.dev/tools/pub/pubspec
30 |
31 | # The following section is specific to Flutter.
32 | flutter:
33 |
34 | # The following line ensures that the Material Icons font is
35 | # included with your application, so that you can use the icons in
36 | # the material Icons class.
37 | uses-material-design: true
38 |
39 | # To add assets to your application, add an assets section, like this:
40 | # assets:
41 | # - images/a_dot_burr.jpeg
42 | # - images/a_dot_ham.jpeg
43 |
44 | # An image asset can refer to one or more resolution-specific "variants", see
45 | # https://flutter.dev/assets-and-images/#resolution-aware.
46 |
47 | # For details regarding adding assets from package dependencies, see
48 | # https://flutter.dev/assets-and-images/#from-packages
49 |
50 | # To add custom fonts to your application, add a fonts section here,
51 | # in this "flutter" section. Each entry in this list should have a
52 | # "family" key with the font family name, and a "fonts" key with a
53 | # list giving the asset and other descriptors for the font. For
54 | # example:
55 | # fonts:
56 | # - family: Schyler
57 | # fonts:
58 | # - asset: fonts/Schyler-Regular.ttf
59 | # - asset: fonts/Schyler-Italic.ttf
60 | # style: italic
61 | # - family: Trajan Pro
62 | # fonts:
63 | # - asset: fonts/TrajanPro.ttf
64 | # - asset: fonts/TrajanPro_Bold.ttf
65 | # weight: 700
66 | #
67 | # For details regarding fonts from package dependencies,
68 | # see https://flutter.dev/custom-fonts/#from-packages
69 |
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .vagrant/
3 | .sconsign.dblite
4 | .svn/
5 |
6 | .DS_Store
7 | *.swp
8 | profile
9 |
10 | DerivedData/
11 | build/
12 | GeneratedPluginRegistrant.h
13 | GeneratedPluginRegistrant.m
14 |
15 | .generated/
16 |
17 | *.pbxuser
18 | *.mode1v3
19 | *.mode2v3
20 | *.perspectivev3
21 |
22 | !default.pbxuser
23 | !default.mode1v3
24 | !default.mode2v3
25 | !default.perspectivev3
26 |
27 | xcuserdata
28 |
29 | *.moved-aside
30 |
31 | *.pyc
32 | *sync/
33 | Icon?
34 | .tags*
35 |
36 | /Flutter/Generated.xcconfig
37 | /Flutter/flutter_export_environment.sh
--------------------------------------------------------------------------------
/ios/Assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeperri/flutter-native-callbacks-example/d89469e0e55e6ef995982fb1ad1db572891f23c7/ios/Assets/.gitkeep
--------------------------------------------------------------------------------
/ios/Classes/NativeCallbacksExamplePlugin.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface NativeCallbacksExamplePlugin : NSObject
4 | @end
5 |
--------------------------------------------------------------------------------
/ios/Classes/NativeCallbacksExamplePlugin.m:
--------------------------------------------------------------------------------
1 | #import "./Shared/CallbackManager.h"
2 |
3 | #import "NativeCallbacksExamplePlugin.h"
4 | #if __has_include()
5 | #import
6 | #else
7 | // Support project import fallback if the generated compatibility header
8 | // is not copied when this plugin is created as a library.
9 | // https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816
10 | #import "native_callbacks_example-Swift.h"
11 | #endif
12 |
13 | @implementation NativeCallbacksExamplePlugin
14 | + (void)registerWithRegistrar:(NSObject*)registrar {
15 | [SwiftNativeCallbacksExamplePlugin registerWithRegistrar:registrar];
16 | }
17 | @end
18 |
--------------------------------------------------------------------------------
/ios/Classes/Shared/CallbackManager.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // CallbackManager.cpp
3 | // native_callbacks_example
4 | //
5 | // Created by M on 5/1/20.
6 | //
7 |
8 | #include
9 | #include "CallbackManager.h"
10 |
11 | Dart_PostCObjectType dartPostCObject = NULL;
12 |
13 | void RegisterDart_PostCObject(Dart_PostCObjectType _dartPostCObject) {
14 | dartPostCObject = _dartPostCObject;
15 | }
16 |
17 | void callbackToDartInt32(Dart_Port callbackPort, int32_t value) {
18 | Dart_CObject dart_object;
19 | dart_object.type = Dart_CObject_kInt32;
20 | dart_object.value.as_int32 = value;
21 |
22 | bool result = dartPostCObject(callbackPort, &dart_object);
23 | if (!result) {
24 | printf("call from native to Dart failed, result was: %d\n", result);
25 | }
26 | }
27 |
28 | void callbackToDartStrArray(Dart_Port callbackPort, int length, char** values) {
29 | Dart_CObject **valueObjects = new Dart_CObject *[length];
30 | int i;
31 | for (i = 0; i < length; i++) {
32 | Dart_CObject *valueObject = new Dart_CObject;
33 | valueObject->type = Dart_CObject_kString;
34 | valueObject->value.as_string = values[i];
35 |
36 | valueObjects[i] = valueObject;
37 | }
38 |
39 | Dart_CObject dart_object;
40 | dart_object.type = Dart_CObject_kArray;
41 | dart_object.value.as_array.length = length;
42 | dart_object.value.as_array.values = valueObjects;
43 |
44 | bool result = dartPostCObject(callbackPort, &dart_object);
45 | if (!result) {
46 | printf("call from native to Dart failed, result was: %d\n", result);
47 | }
48 |
49 | for (i = 0; i < length; i++) {
50 | delete valueObjects[i];
51 | }
52 | delete[] valueObjects;
53 | }
54 |
--------------------------------------------------------------------------------
/ios/Classes/Shared/CallbackManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // CallbackManager.h
3 | // native_callbacks_example
4 | //
5 | // Created by M on 5/1/20.
6 | //
7 |
8 | #ifndef CallbackManager_h
9 | #define CallbackManager_h
10 |
11 | #include
12 | #include
13 |
14 | // dart_api.h
15 | typedef int64_t Dart_Port;
16 |
17 | typedef enum {
18 | Dart_TypedData_kByteData = 0,
19 | Dart_TypedData_kInt8,
20 | Dart_TypedData_kUint8,
21 | Dart_TypedData_kUint8Clamped,
22 | Dart_TypedData_kInt16,
23 | Dart_TypedData_kUint16,
24 | Dart_TypedData_kInt32,
25 | Dart_TypedData_kUint32,
26 | Dart_TypedData_kInt64,
27 | Dart_TypedData_kUint64,
28 | Dart_TypedData_kFloat32,
29 | Dart_TypedData_kFloat64,
30 | Dart_TypedData_kFloat32x4,
31 | Dart_TypedData_kInvalid
32 | } Dart_TypedData_Type;
33 |
34 | typedef struct _Dart_WeakPersistentHandle* Dart_WeakPersistentHandle;
35 |
36 | typedef void (*Dart_WeakPersistentHandleFinalizer)(
37 | void* isolate_callback_data,
38 | Dart_WeakPersistentHandle handle,
39 | void* peer);
40 |
41 | // dart_native_api.h
42 | typedef enum {
43 | Dart_CObject_kNull = 0,
44 | Dart_CObject_kBool,
45 | Dart_CObject_kInt32,
46 | Dart_CObject_kInt64,
47 | Dart_CObject_kDouble,
48 | Dart_CObject_kString,
49 | Dart_CObject_kArray,
50 | Dart_CObject_kTypedData,
51 | Dart_CObject_kExternalTypedData,
52 | Dart_CObject_kSendPort,
53 | Dart_CObject_kCapability,
54 | Dart_CObject_kUnsupported,
55 | Dart_CObject_kNumberOfTypes
56 | } Dart_CObject_Type;
57 |
58 | typedef struct _Dart_CObject {
59 | Dart_CObject_Type type;
60 | union {
61 | bool as_bool;
62 | int32_t as_int32;
63 | int64_t as_int64;
64 | double as_double;
65 | char* as_string;
66 | struct {
67 | Dart_Port id;
68 | Dart_Port origin_id;
69 | } as_send_port;
70 | struct {
71 | int64_t id;
72 | } as_capability;
73 | struct {
74 | intptr_t length;
75 | struct _Dart_CObject** values;
76 | } as_array;
77 | struct {
78 | Dart_TypedData_Type type;
79 | intptr_t length;
80 | uint8_t* values;
81 | } as_typed_data;
82 | struct {
83 | Dart_TypedData_Type type;
84 | intptr_t length;
85 | uint8_t* data;
86 | void* peer;
87 | Dart_WeakPersistentHandleFinalizer callback;
88 | } as_external_typed_data;
89 | } value;
90 | } Dart_CObject;
91 |
92 | typedef bool (*Dart_PostCObjectType)(Dart_Port port_id, Dart_CObject* message);
93 |
94 | #ifdef __cplusplus
95 | extern "C" {
96 | #endif
97 | void RegisterDart_PostCObject(Dart_PostCObjectType _dartPostCObject);
98 | void callbackToDartInt32(Dart_Port callbackPort, int32_t value);
99 | void callbackToDartStrArray(Dart_Port callbackPort, int length, char** values);
100 | #ifdef __cplusplus
101 | }
102 | #endif
103 |
104 | #endif /* CallbackManager_h */
105 |
--------------------------------------------------------------------------------
/ios/Classes/SwiftNativeCallbacksExamplePlugin.swift:
--------------------------------------------------------------------------------
1 | import Flutter
2 | import UIKit
3 |
4 | public class SwiftNativeCallbacksExamplePlugin: NSObject, FlutterPlugin {
5 | public static func register(with registrar: FlutterPluginRegistrar) {
6 | let channel = FlutterMethodChannel(name: "native_callbacks_example", binaryMessenger: registrar.messenger())
7 | let instance = SwiftNativeCallbacksExamplePlugin()
8 | registrar.addMethodCallDelegate(instance, channel: channel)
9 | }
10 |
11 | public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
12 | result("iOS " + UIDevice.current.systemVersion)
13 | }
14 | }
15 |
16 | func swiftCallbackToDartStrArray(callbackPort: Dart_Port, values: [String]) -> Void {
17 | withArrayOfCStrings(values) { (cStrings: [UnsafeMutablePointer?]) in
18 | var cStringsVariable = cStrings
19 |
20 | callbackToDartStrArray(
21 | callbackPort,
22 | Int32(values.count),
23 | &cStringsVariable
24 | )
25 | }
26 | }
27 |
28 | @_cdecl("method_a")
29 | func methodA(callbackPort: Dart_Port) {
30 | print("Started method A")
31 | let number = Int32(123)
32 |
33 | DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 1) {
34 | callbackToDartInt32(
35 | callbackPort,
36 | number
37 | )
38 | print("Finished method A")
39 | }
40 | }
41 |
42 | @_cdecl("method_b")
43 | func methodB(callbackPort: Dart_Port) {
44 | print("Started method B")
45 | let strings = ["abc", "def"]
46 |
47 | DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 2) {
48 | swiftCallbackToDartStrArray(
49 | callbackPort: callbackPort,
50 | values: strings
51 | )
52 | print("Finished method B")
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/ios/Classes/Utils.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Utils.swift
3 | // native_callbacks_example
4 | //
5 | // Created by M on 5/2/20.
6 | //
7 |
8 | import Foundation
9 |
10 | func scan<
11 | S : Sequence, U
12 | >(_ seq: S, _ initial: U, _ combine: (U, S.Iterator.Element) -> U) -> [U] {
13 | var result: [U] = []
14 | result.reserveCapacity(seq.underestimatedCount)
15 | var runningResult = initial
16 | for element in seq {
17 | runningResult = combine(runningResult, element)
18 | result.append(runningResult)
19 | }
20 | return result
21 | }
22 |
23 | public func withArrayOfCStrings(
24 | _ args: [String],
25 | _ body: ([UnsafeMutablePointer?]) -> R
26 | ) -> R {
27 | let argsCounts = Array(args.map { $0.utf8.count + 1 })
28 | let argsOffsets = [ 0 ] + scan(argsCounts, 0, +)
29 | let argsBufferSize = argsOffsets.last!
30 |
31 | var argsBuffer: [UInt8] = []
32 | argsBuffer.reserveCapacity(argsBufferSize)
33 | for arg in args {
34 | argsBuffer.append(contentsOf: arg.utf8)
35 | argsBuffer.append(0)
36 | }
37 |
38 | return argsBuffer.withUnsafeMutableBufferPointer {
39 | (argsBuffer) in
40 | let ptr = UnsafeMutableRawPointer(argsBuffer.baseAddress!).bindMemory(
41 | to: CChar.self, capacity: argsBuffer.count)
42 | var cStrings: [UnsafeMutablePointer?] = argsOffsets.map { ptr + $0 }
43 | cStrings[cStrings.count - 1] = nil
44 | return body(cStrings)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/ios/native_callbacks_example.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
3 | # Run `pod lib lint native_callbacks_example.podspec' to validate before publishing.
4 | #
5 | Pod::Spec.new do |s|
6 | s.name = 'native_callbacks_example'
7 | s.version = '0.0.1'
8 | s.summary = 'A new flutter plugin project.'
9 | s.description = <<-DESC
10 | A new flutter plugin project.
11 | DESC
12 | s.homepage = 'http://example.com'
13 | s.license = { :file => '../LICENSE' }
14 | s.author = { 'Your Company' => 'email@example.com' }
15 | s.source = { :path => '.' }
16 | s.source_files = 'Classes/**/*'
17 | s.xcconfig = { 'USER_HEADER_SEARCH_PATHS' => '"${PROJECT_DIR}/.."/Classes/Shared/*' }
18 | s.dependency 'Flutter'
19 | s.platform = :ios, '8.0'
20 |
21 | # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported.
22 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }
23 | s.swift_version = '5.0'
24 | end
25 |
--------------------------------------------------------------------------------
/lib/native_callbacks_example.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:ffi';
3 | import 'dart:io';
4 | import 'package:isolate/ports.dart';
5 |
6 | final DynamicLibrary nativeLib = Platform.isAndroid
7 | ? DynamicLibrary.open('libandroid_native_callbacks_example.so')
8 | : DynamicLibrary.executable();
9 |
10 | final nRegisterPostCObject = nativeLib.lookupFunction<
11 | Void Function(
12 | Pointer)>>
13 | functionPointer),
14 | void Function(
15 | Pointer)>>
16 | functionPointer)>('RegisterDart_PostCObject');
17 |
18 | final nMethodA = nativeLib
19 | .lookupFunction('method_a');
20 |
21 | final nMethodB = nativeLib
22 | .lookupFunction('method_b');
23 |
24 | class NativeCallbacksExample {
25 | // Must be called once, before any other method
26 | static void doSetup() {
27 | nRegisterPostCObject(NativeApi.postCObject);
28 | }
29 |
30 | static Future methodA() async {
31 | return singleResponseFuture((port) => nMethodA(port.nativePort));
32 | }
33 |
34 | static Future> methodB() async {
35 | final future = singleResponseFuture>((port) => nMethodB(port.nativePort));
36 | return future.then((List list) {
37 | return list.cast();
38 | });
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/native_callbacks_example.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | collection:
5 | dependency: transitive
6 | description:
7 | name: collection
8 | url: "https://pub.dartlang.org"
9 | source: hosted
10 | version: "1.14.12"
11 | flutter:
12 | dependency: "direct main"
13 | description: flutter
14 | source: sdk
15 | version: "0.0.0"
16 | isolate:
17 | dependency: "direct main"
18 | description:
19 | name: isolate
20 | url: "https://pub.dartlang.org"
21 | source: hosted
22 | version: "2.0.3"
23 | meta:
24 | dependency: transitive
25 | description:
26 | name: meta
27 | url: "https://pub.dartlang.org"
28 | source: hosted
29 | version: "1.1.8"
30 | sky_engine:
31 | dependency: transitive
32 | description: flutter
33 | source: sdk
34 | version: "0.0.99"
35 | typed_data:
36 | dependency: transitive
37 | description:
38 | name: typed_data
39 | url: "https://pub.dartlang.org"
40 | source: hosted
41 | version: "1.1.6"
42 | vector_math:
43 | dependency: transitive
44 | description:
45 | name: vector_math
46 | url: "https://pub.dartlang.org"
47 | source: hosted
48 | version: "2.0.8"
49 | sdks:
50 | dart: ">=2.7.0 <3.0.0"
51 | flutter: ">=1.18.0-8.0.pre"
52 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: native_callbacks_example
2 | description: An example of a Flutter plugin that calls directly into native code and gets an asynchronous callback
3 | version: 0.0.1
4 | author:
5 | homepage:
6 |
7 | environment:
8 | sdk: ">=2.7.0 <3.0.0"
9 | flutter: ">=1.18.0-8.0.pre"
10 |
11 | dependencies:
12 | flutter:
13 | sdk: flutter
14 | isolate: "^2.0.3"
15 |
16 | # For information on the generic Dart part of this file, see the
17 | # following page: https://dart.dev/tools/pub/pubspec
18 |
19 | # The following section is specific to Flutter.
20 | flutter:
21 | # This section identifies this Flutter project as a plugin project.
22 | # The 'pluginClass' and Android 'package' identifiers should not ordinarily
23 | # be modified. They are used by the tooling to maintain consistency when
24 | # adding or updating assets for this project.
25 | plugin:
26 | platforms:
27 | android:
28 | package: com.example.native_callbacks_example
29 | pluginClass: NativeCallbacksExamplePlugin
30 | ios:
31 | pluginClass: NativeCallbacksExamplePlugin
32 |
33 | # To add assets to your plugin package, add an assets section, like this:
34 | # assets:
35 | # - images/a_dot_burr.jpeg
36 | # - images/a_dot_ham.jpeg
37 | #
38 | # For details regarding assets in packages, see
39 | # https://flutter.dev/assets-and-images/#from-packages
40 | #
41 | # An image asset can refer to one or more resolution-specific "variants", see
42 | # https://flutter.dev/assets-and-images/#resolution-aware.
43 |
44 | # To add custom fonts to your plugin package, add a fonts section here,
45 | # in this "flutter" section. Each entry in this list should have a
46 | # "family" key with the font family name, and a "fonts" key with a
47 | # list giving the asset and other descriptors for the font. For
48 | # example:
49 | # fonts:
50 | # - family: Schyler
51 | # fonts:
52 | # - asset: fonts/Schyler-Regular.ttf
53 | # - asset: fonts/Schyler-Italic.ttf
54 | # style: italic
55 | # - family: Trajan Pro
56 | # fonts:
57 | # - asset: fonts/TrajanPro.ttf
58 | # - asset: fonts/TrajanPro_Bold.ttf
59 | # weight: 700
60 | #
61 | # For details regarding fonts in packages, see
62 | # https://flutter.dev/custom-fonts/#from-packages
63 |
--------------------------------------------------------------------------------