Skip to content

[Add2App] provide flag for 'build ios-framework' command to build only App.xcframework #114692

@p-mazhnik

Description

@p-mazhnik

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).

  • FlutterModule depends on third-party Flutter plugins, some of them have iOS dependencies, e.g. sentry_flutter which depends on Sentry pod.
  • IOSApp also uses CocoaPods to 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.

Sentry example

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.podspec in my case, if --cocoapods flag 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 its podspec, frameworks will be built for each of them. Undesired: Pod2 can 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 FlutterModule I have to make sure it doesn't include CocoaPods dependency that conflicts with CocoaPods dependency of IOSApp. (Note that Sentry pod wasn't the only that caused issues)
  • as a result of the previous I can't safely publish my FlutterModule itself as a CocoaPods dependency to be consumed by any iOS apps
  • because flutter build ios-framework produces 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 --cocoapods flag and generate another podspec with all third-party pods listed.
  • Option 2: flag to build only App.xcframework
    All we need to do is to prevent _producePlugins function 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: existing-appsIntegration with existing apps via the add-to-app flowc: new featureNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to Flutterplatform-iosiOS applications specificallyteam-iosOwned by iOS platform teamtoolAffects the "flutter" command-line tool. See also t: labels.triaged-iosTriaged by iOS platform team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions