You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Federated Plugins] Provide a way to override a default/endorsed platform implementation #80374
It would be desirable for a federated plugin to have a default implementation for iOS, either inside the plugin or an endorsed separate package, and to then allow apps to choose an alternative platform implementation to override that default. E.g. for just_audio, we will have a default AVQueuePlayer-based implementation, but an alternative AudioKit implementation and an alternative VLC implementation.
However, I don't think this override ability has been added to Flutter yet, although it was implied in the design doc.
What happens instead is that the generated plugin registrant will automatically add both the default/endorsed plugin AND any additional plugin the app adds to their pubspec with the intention of overriding the default. Since both are listed, alphabetical order will dictate which one is effective.
Proposal
Currently a platform implementation is endorsed by adding its dependency to the plugin's front-end and so it's going to get added to the generated plugin registrant regardless of any attempt to override it.
I'm not sure on the best solution, but maybe either the mechanism to endorse an implementation needs to be something other than a normal dependency, or otherwise the flutter tool should add some special cases to the code that generates the generated plugin registrant to detect overrides and avoids adding both the override and the default.
The PR for #52267 has logic to handle this for Dart plugin registration; we should be able to extend that same logic to any native plugin implementation.
By my understanding, that PR describes configuration changes to the plugins themselves, but I'm trying to understand what an app developer would need to configure to choose the overriding platform. Currently we would do something like this in the app's pubspec:
where just_audio already includes a default iOS implementation, and each of those two packages would define . What mechanism controllable by the app itself can prevent the default implementation from loading? I assumed the plugin class is a property of the plugin rather than the app, but would the app need to define the plugin class for each override plugin it uses, in addition to adding the package dependency?
/// Resolves the platform implementation for Dart-only plugins.
///
/// * If there are multiple direct pub dependencies on packages that implement the
/// frontend plugin for the current platform, fail.
/// * If there is a single direct dependency on a package that implements the
/// frontend plugin for the target platform, this package is the selected implementation.
/// * If there is no direct dependency on a package that implements the frontend
/// plugin for the target platform, and the frontend plugin has a default implementation
/// for the target platform the default implementation is selected.
/// * Else fail.
///
/// For more details, https://flutter.dev/go/federated-plugins.
Thanks, I think I understand the algorithm.
I was slightly confused by the wording above, because just_audio could be considered as providing a default iOS implementation itself, but it could also be considered as being a "direct pub dependency that implements the frontend plugin for the current platform".
Are there tendencies, how this will be approached?
The comments above yours describe how this will be implemented.
You already wrote two solutions here, although they do not exclude each other and the second one does not solve the problem of this thread directly: #81650 (comment)
My comment there is not about solutions to this issue; it's about solving a different problem.
But still, I haven't looked into the code and don't know if it's actually possible to prevent a native plugin from registering
This will, when implemented, cause the overridden implementation not to be registered.
The comments above yours describe how this will be implemented.
Yes, now I got it. I just never saw how this actually is implemented in the pubspec.yaml . But I found also the exact code line now.
So in dart it just works by adding a direct dependency to the developers application, it automatically detects if it has an implementation of an existing plugin package. And then prefer the direct dependency over the default one.
I was always the opinion one needs to actually declare the plugin override in the pubspec via the flutter params, but that isn't the case.
And it's already described in words here for non-endorsed plugins:
So the registration for the alternative native plugin is already working, just the deregistration of the default one is not yet. I may have a deeper look into this.
I created a PR now (#137040) which aims to solve this issue. It's not ready yet (missing parts are listed in the PR description), but maybe one can comment, if it's leading in the right direction and one can have a look in the TODOs in the code.
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.
Activity
stuartmorgan-g commentedon Apr 13, 2021
The PR for #52267 has logic to handle this for Dart plugin registration; we should be able to extend that same logic to any native plugin implementation.
ryanheise commentedon Apr 14, 2021
By my understanding, that PR describes configuration changes to the plugins themselves, but I'm trying to understand what an app developer would need to configure to choose the overriding platform. Currently we would do something like this in the app's pubspec:
where just_audio already includes a default iOS implementation, and each of those two packages would define . What mechanism controllable by the app itself can prevent the default implementation from loading? I assumed the plugin class is a property of the plugin rather than the app, but would the app need to define the plugin class for each override plugin it uses, in addition to adding the package dependency?
stuartmorgan-g commentedon Apr 14, 2021
https://github.com/flutter/flutter/pull/79669/files#diff-68361f6fc9aafa5fa7de042eec4603dd4f321eb783a00edd57780ef78c1094bbR1051-R1060
ryanheise commentedon Apr 14, 2021
Thanks, I think I understand the algorithm.
I was slightly confused by the wording above, because
just_audiocould be considered as providing a default iOS implementation itself, but it could also be considered as being a "direct pub dependency that implements the frontend plugin for the current platform".ryanheise commentedon May 28, 2022
Is the way to override an endorsed platform implementation now documented anywhere in the latest up-to-date documentation on federated plugins?
stuartmorgan-g commentedon May 31, 2022
No; we're unlikely to formally document this until it works for native code as well, otherwise it will be very confusing.
5 remaining items
stuartmorgan-g commentedon Oct 17, 2023
The comments above yours describe how this will be implemented.
My comment there is not about solutions to this issue; it's about solving a different problem.
This will, when implemented, cause the overridden implementation not to be registered.
Gustl22 commentedon Oct 18, 2023
Yes, now I got it. I just never saw how this actually is implemented in the
pubspec.yaml. But I found also the exact code line now.So in dart it just works by adding a direct dependency to the developers application, it automatically detects if it has an implementation of an existing plugin package. And then prefer the direct dependency over the default one.
I was always the opinion one needs to actually declare the plugin override in the pubspec via the
flutterparams, but that isn't the case.And it's already described in words here for non-endorsed plugins:
So the registration for the alternative native plugin is already working, just the deregistration of the default one is not yet. I may have a deeper look into this.
Gustl22 commentedon Oct 19, 2023
Quick update to an implementation, which works for me by removing the default plugin as follows:
.flutter-pluginsfile) if it has more than one native implementation (at least I think that could be possible).Gustl22 commentedon Oct 22, 2023
I created a PR now (#137040) which aims to solve this issue. It's not ready yet (missing parts are listed in the PR description), but maybe one can comment, if it's leading in the right direction and one can have a look in the TODOs in the code.
Hope it can help to solve this issue :D
refactor: Rename filterPluginsByPlatform, cleanup Platform Strings (#…
refactor: Differentiate pubspec and resolution errors for plugins (#1…
refactor: Remove `throwOnPluginPubspecError` flag for plugin validati…
refactor: Perform plugin resolution per platform (#144506)
refactor: Perform plugin resolution per platform (flutter#144506)
feat: Rework getting plugin implementation candidates and plugin reso…
feat: Support overriding native endorsed plugins (#137040)
github-actions commentedon Jul 25, 2024
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.