-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
Feature request: provide flag for flutter build ios-framework command to build only App.xcframework
or to prevent building of third-party pod dependencies as frameworks
Use case
I have a Flutter module (let's say FlutterModule) integrated to an iOS app (IOSApp) using frameworks. My setup is similar to Option C from the add-to-app doc for iOS (with an improvement of embedding application and plugin frameworks to XCode automatically using CocoaPods).
FlutterModuledepends on third-party Flutter plugins, some of them have iOS dependencies, e.g.sentry_flutterwhich depends onSentrypod.IOSAppalso usesCocoaPodsto add third-party iOS dependencies.
The problem appears when I want to add to IOSApp's Podfile a dependency that reference another dependency that is referenced by Flutter plugin. This can be hard to understand, so here is the schema:
IOSApp -> Pod1 -> Pod2
IOSApp -> flutter_plugin.xcframework -> Pod2.xcframework
So my IOSApp and FlutterModule have the same transitive platform dependency.
Because Pod2 is included twice, first through CocoaPods and second directly as a framework, this causes multiple Redefinition of issues in XCode.
Note that behavior will be the same for case
IOSApp->Pod2
IOSApp->flutter_plugin.xcframework->Pod2.xcframework
Currently flutter build ios-framework command produces following outputs for the build mode:
App.xcframework(desired, compiled Dart code)Flutter.xcframework(Flutter.podspecin my case, if--cocoapodsflag is provided. Desired)FlutterPluginRegistrant.xcframework(desired, registration code for plugins)flutter_plugin.xcframework(desired, each plugin is a separate framework)Pod2.xcframework(If plugin has dependencies in itspodspec, frameworks will be built for each of them. Undesired:Pod2can be also included to iOS app as a dependency, causing issues)
I didn't create this as an issue because obviously I can just remove the duplicated frameworks from the Flutter command output to not include them. UPD: submit an issue #130220 because this workaround is not working for some plugins, like datadog_flutter_plugin
But this solution is not universal. Some downsides are:
- each time I add new dependency to
FlutterModuleI have to make sure it doesn't include CocoaPods dependency that conflicts with CocoaPods dependency ofIOSApp. (Note thatSentrypod wasn't the only that caused issues) - as a result of the previous I can't safely publish my
FlutterModuleitself as a CocoaPods dependency to be consumed by any iOS apps - because
flutter build ios-frameworkproduces frameworks that will be removed right after the creation, this has a significant impact on build time. We can speed up this command by preventing the build of undesired frameworks.
Proposal
Modify build ios-framework command to support this use case. I thought about two options:
- Option 1: flag to prevent third-party pod dependencies to be built as frameworks.
Current solution is to build every target from.ios/Pods/Pods.xcodeproj(see _producePlugins function). Targets include both Flutter plugins and their pod dependencies. We can try to change this, but I am not sure if it is possible to build only selected targets without building their dependencies.
Another question here is how to then easily include all of the remaining pods dependencies to app. Probably we can combine this with--cocoapodsflag and generate anotherpodspecwith all third-party pods listed. - Option 2: flag to build only
App.xcframework
All we need to do is to prevent_producePluginsfunction from running. Inclusion of the pods dependencies to the app will be developer's responsibility and not the Flutter's (unlike in Option 1, it's easy to do)
I personally implemented Option 2 in my FlutterModule project because it was easier to include pods from Flutter plugins. I had to create a custom build command based on the BuildIOSFrameworkCommand class to prevent the _producePlugins function from running. As a result, only App.xcframework was generated. In order to include Flutter plugins, their dependencies and FlutterPluginRegistrant, I combined this solution with Option A from the add-to-app doc. Basically, for each flutter_plugin included a podspec from .ios/.symlinks/plugins/<flutter_plugin>/ios/<flutter_plugin>.podspec and for the FlutterPluginRegistrant a podspec from .ios/Flutter/FlutterPluginRegistrant/FlutterPluginRegistrant.podspec.
So the main goal for me personally is to remove the custom build command (also BuildIOSFrameworkCommand class has a lot of private methods that I had to copy-paste to the subclass) and use a solution provided by Flutter. And I think it can be a good improvement in general. It also could help writing iOS version of flutter/website#7775 because it currently seems impossible to easily share the same transitive platform dependency between Flutter module and iOS app
Please let me know if I misunderstood something and my use case can be achieved in some existing way
