-
Notifications
You must be signed in to change notification settings - Fork 28.5k
Import multiple Flutter modules in a native app #39707
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thanks for describing in detail. This concept is on our mind but likely not something we'll support in an MVP this year. The main work here is to split our deliverables from being 2 pieces (libflutter.so + libapp.so or Flutter.framework + App.framework) into 3 pieces: 1- the Flutter C++ engine with small bits in Java/Objective-C (1) and a bunch of tooling dealing with mismatches. In the meantime, you'll likely need to create a glue project to bring in all your Flutter modules together in CI or manually before importing like you suggested. |
Copying in from #40343 From @Vanethos: ObjectiveCreate a native library for iOS and Android that has Flutter bundled in so that native developers can use this library without the need of installing flutter Steps taken
This gives the following outcome:
The instruction followed were the ones in the following link: adding flutter aar file to an android app What is noticed is that if the same steps are used to add flutter to an android host, as is detailed in the guide, then the code can compile and it all works out in an emulator. I've also created a repository with a minimal example to reproduce the issue: https://github.com/Vanethos/modulated-add-to-app
As requested, I'll tag @blasten in this issue |
@xster thank you for merging the issue As I understand you said that this will not have any new updates during this year? |
Right. Unless we see signs of this being a more common pattern, there are more pressing issues we're currently focused on this year. |
Well, unfortunately, that means that I'll have to port my codebase to native :( |
Can you accomplish the same thing by creating and re-using Flutter plugins, and importing them into your existing app with a single module? |
@jmagman the problem is that we are doing this to create a native library to be used in Android and iOS. Our clients don't have flutter installed in their machines and some of them will not be able to. So we need to be able to compile a sort of .aar and pod that has native code, flutter code and the flutter engine Since we need this to work before the end of the year, unfortunately, I'm already porting our codebase to swift and kotlin (3 code bases to manage,yay!...) |
@Vanethos The aar work is done, instructions here: https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps#1-depend-on-the-android-archive-aar @arctouch-matheusromao Could you implement the It looks like this issue may need to have the errors you documented split out into several trackable issues. |
Hey @jmagman, Those modules were here just for the sake of the explanation. Our work environment revolves around various products, some new and other already existent. We would like to be able to share different modules across different projects. Some of those modules could be plugins, but unfortunately, others can't, as they would have UI flows. Actually, we do have a use-case that we could implement plugins and consume that inside one module. But, that's just one module. Just to be more clear, let's say we have a restaurant and we already have an Android app for our waiters to handle the orders. But our business is growing and we are already midway through the iOS native app development for our users to pay. Finally, we do have plans to build another app to handle all the back-office operations. So, for our restaurant we have three projects:
At this point, we already have designs for our brand and we want to preserve that across the apps. So, there are a lot of features that could be shared between those projects. For example, we have I hope this example helps to clarify why some business may choose to use Flutter. This would be an incredible opportunity to get work done faster than in any other framework and help a lot of businesses. |
@jmagman but, as I have discussed in my issue, my problem is not adding the aar to an app but it is a problem adding an aar to a module. Unfortunately the native implementation has already started.. :'( |
@xster and @matthew-carroll, do you guys know if it's possible to send messages through a Platform Channel between a Flutter module and a Flutter app? In our context here (explained in this issue), I'm exposing the umbrella module to an iOS app, which consumes all the events from our modules using a channel. That is working nicely. Now we need to import those modules inside a Flutter app. I fell like I don't need to import the umbrella and just import directly the modules that I need. In the example above, say I want to import the login module inside my Flutter app, but the login module already has an implemented channel, which sends user events. How can I listen to that inside the Flutter app? I thought I could just do that in the Flutter app: final channel = MethodChannel(channelName);
channel.setMethodCallHandler(_handler) Where However, it doesn't work. Here's the output:
Is there a way that I can use the same I know I can just pass a handler method to the module, but that would also mean changes in the implementation inside the module. Right now we are trying to avoid this path. Thanks! |
It sounds like the issue with the I'm curious, if you have componentized capabilities that involve Dart and platform behavior, why not turn those into local plugins and then consume those plugins in your Flutter app? |
Yeah I was curious, too. I don't exactly see why this won't work for the originator. From my comment above:
And the response:
|
Thanks, @matthew-carroll! I went with a hybrid solution, having a package responsible to use channels for the bridge between modules and existent native apps and a About your question, our biggest problem is that each componentized capability has UI flows in Flutter and we need to integrate that in different native apps, that's why we don't use plugins over modules. |
@jmagman, is it possible to have UI ( What I meant with "Some of those modules could be plugins" is that we can separate things like the business logic for the login and register, handling authentication and all of that (following the example). However, that's not a sufficient reason to import Flutter inside a native app. If we still need to create the UI in the native project, why import Flutter in the first place? We would like to import Flutter and use it like a "black box" sending inputs to modules, so they can handle everything inside of it (based on its purpose) and when the flow is done, we can come back to the native app with some output of the process. |
Perhaps @jmagman or @xster will be able to provide the solution, but I'm afraid I'm getting a bit lost between umbrella project and module projects and native projects. Would it be possible for you to post a simple diagram that shows what you have now, and then perhaps another diagram of where you're trying to get to? If not, that's fine, but I'm not sure I'll be able to follow the goal. |
Hi @arctouch-matheusromao I have the same issue with you.
I don't how to create routes in the umbrella module when call from native. |
Hey @ngminhduong, follow the solution we've followed: UmbrellaModule: void main() => runApp(UmbrellaApp(route: window.defaultRouteName));
class UmbrellaApp extends StatelessWidget {
final String route;
UmbrellaApp(this.route);
@override
Widget build(BuildContext context) {
switch (route) {
// UmbrellaModule is class holding static strings.
case UmbrellaModules.login: // UmbrellaModules.login = 'login_module'
return LoginModule();
case UmbrellaModules.register:
return RegisterModule();
default:
return ErrorRoute();
}
}
} iOS-native app: let flutterViewController = UmbrellaViewController()
flutterViewController.setInitialRoute("oobe_module")
self.present(flutterViewController, animated: false, completion: nil) Where: class UmbrellaViewController: FlutterViewController |
Hey @arctouch-matheusromao It work for me |
Hi @arctouch-matheusromao, @matthew-carroll let flutterViewController = UmbrellaViewController()
flutterViewController.setInitialRoute("oobe_module")
self.present(flutterViewController, animated: false, completion: nil) Splash screen always shows before Flutter viewController appears. Issue not happened if we init view controller by this way: let flutterEngine = (UIApplication.shared.delegate as! AppDelegate).flutterEngine
let flutterViewController = UmbrellaViewController(engine: flutterEngine, nibName: nil, bundle: nil)
self.present(flutterViewController, animated: false, completion: nil) But setInitialRoute not work. Do you have any solution for this issue? Thanks, |
@arctouch-matheusromao I'm having an issue with the Umbrella work around. My assets (images) are not loading in my imported modules. Everything else is working just seems that the assets from their respective pubspec.yaml files are not being loaded. Wondering if you've had a run in with this? |
Hey @mikhail-karan, you have to be careful with the |
This comment has been minimized.
This comment has been minimized.
@gaaclarke In light of #72009 and https://github.com/flutter/samples/tree/master/add_to_app/multiple_flutters can you update this issue with what additional work this is tracking (if any?) |
@jmagman My understanding of this issue is that it isn't related to multiple flutters directly. Multiple flutters allows you to have multiple entry points into your module at low memory / time cost. This has to do with having multiple modules on disk you want to load up. The multiple-flutters work should help that effort but I imagine there is some tooling / documentation we need to support multiple modules on disk still. For example, one of the issues they were running into was the build failing because it was finding multiple libflutter.so files. |
Right, this is about being able to do https://flutter.dev/docs/development/add-to-app/ios/project-setup#option-a---embed-with-cocoapods-and-the-flutter-sdk twice by calling FWIW, this may or may not be useful for everyone, but a partial work around would be to split the Flutter functionalities into different Dart packages and let the top Dart package loop in the various feature Dart packages via pubspec.yaml before building an AAR/framework/pod/gradle subproject once per app. |
I have a slightly different issue (#86790) where I would like to embed a Flutter module in an existing Flutter application. Having an umbrella module here is not an option. |
This comment was marked as duplicate.
This comment was marked as duplicate.
@xster @jmagman any updates on this issue? More and more requirements are coming through in this space specially from super app - mini app perspective where multiple flutter modules fit in perfectly. With the current roadblock I am forced to move away from flutter albeit being my core dev platform to React Native or Hybrid HTML5 based approaches. Is this feature being prioritised or Are there any other work around using packages/ plugins to implement mini apps contain UI and logic to be wrapped in a container app? Pls Advise!! |
Maybe this library helps you: https://pub.dev/packages/flutter_eval |
Thanks @ldasilva-net Looks like package is in the initial stages and supports limited set of widgets and packages not sure whether its production ready. Nevertheless the concept is very interesting. |
Just wanted to share a possible solution we are trying. If everyone involved is willing to share sources, you can create an umbrella module with routes to the various components like this Inside the umbrella module: pubpec.yaml:
main.dart:
Inside the main Android app: MainActivity.java:
settings.gradle:
Of course, this requires the entire flutter source code for all the modules, but we did not see any way around this. |
I have same question,The simplest case steps(add2App):
How to resolve the question same name framwork and run success?how to import two flutter module framework? By the way, we can not use the plugin ways ,because these two flutter modules are different company projects, It can not provide source code to each other. My flutter version is 3.7.1, but I think this question has nothing to do with flutter version. Looking forward to solving this problem! |
met with the same problem. can't add new flutter module to the native project (more precisely, in projects for each platform iOS and Android). Now the new part of the project is implemented in a separate new flutter module. PS Flutter modules are connected to the project as artifacts. If we talk about android, the host project pulls up the repository with aar. |
May I ask does flutter now still not support adding more than 1 flutter module to native? I am just trying to add more than 1 module to ios but it seems I cannot do this in pod file. Thanks |
I think so, @tong-k-k . |
Can you share the solution to do it? |
Hello guys,
I'm Matheus Romão, software engineer at ArcTouch. Here, we are going with Flutter as the technology choice for an important project but recently hit a major roadblock. The principal difficulty relates to using different Flutter modules on different projects. Further explanation and proposal can be found on this issue.
TL;DR: We would like to import different modules in the same project, so we could reuse them in different projects. Today if we try that, we won't pass from Project Sync on Android or
pod install
on iOS.Use case
Following the add-to-app guide we can import a Flutter module to an existing native app. However, there's no way to import multiple modules and access each module unitarily.
For example, if we have the following structure:
It would be nice if there were a way to import
login
andregister
modules depending on the needs of each project, so we could reuse them.Android
Following the "depend on the module's source code" method, I was able to "import" both modules (login and register, in the example) leaving one of the
include_flutter.groovy
script as it is and changing the other, renaming:flutter
to:register
. I'm no specialist in gradle/groovy, but I'm pretty sure that was a workaround to make the script work in project sync phase because if you change:flutter
to another name in both scripts, the project sync won't work, it will raise an exception:Anyway, the project sync works if you leave one script as it is and change the other. However, if you try to run the app, even without using Flutter inside of it, the build fails with the following exception:
Which makes sense for me as I'm trying to import Flutter twice.
If I try to import the modules following the "Depend on the Android Archive (AAR)" method, the project sync works. But when you try to run the app the build fails with the following message:
Same problem with duplicates.
iOS
I wasn't able to import the modules using a Podfile. First,
install_all_flutter_pods
accepts only one module and if we try to call that twice in the same target, we get an error:But I went to
podhelper.rb
to check the reference and foundinstall_flutter_application_pod
, so I tried to run the following Podfile:But I still got the same error "script phase already present for target".
Workaround
At last, discussing all of that with my colleagues, they suggested trying to import all the modules in an umbrella-like project and then import in the native app. So, I tried to import both modules as packages of a third module, here called
umbrella
:umbrella/pubspec.yaml
:That works, but you have to create the routes in the
umbrella
module to map thelogin
andregister
widgets.Well, clearly this is not desirable and it feels pretty hacky. In addition, it adds one more layer to the import process and depending on the method you use, you'll have to repeat some steps as the need for modules change.
Proposal
We should be able to import each module and access its features individually.
For Android, it would be great if we could import Flutter engine and then the modules:
After that, we could specify which module and route we want to use in the Flutter view/fragment/activity (facade or Android embedding). Also, the same idea applies to ".aar" method.
For iOS, we could do something like the Podfile above, calling
install_flutter_application_pod
for each module we want to import or even use varags to pass an array of modules oninstall_all_flutter_pods
.Thank you guys for taking your time to read this (sorry for the long issue)!
The text was updated successfully, but these errors were encountered: