Repository navigation
Reliable way of detecting if a plugin supports Android, or iOS, or both #10288
Description
Activity
- addedp: toolingAffects the flutter_plugin_tools packageAffects the flutter_plugin_tools package
on May 24, 2017 Presumably something like this could also be used as part of validation during publishing (e.g. #9799)
pub.dartlang.org is waiting on guidance from our team as to how to determine this before displaying a list of "flutter" packages and whether they support iOS or Android.
We discussed this a bit, and are starting to form the following picture:
-
Flutter package consumers should not need to know if any given package on Pub is a pure-Dart package that depends on Flutter, or a Dart+native package/plugin written for Flutter -- this may entirely be an implementation detail with no impact to the API surface, so how would they now?! Thus, when searching on pub, you probably just want to search for all Flutter packages (i.e., the sum of pure-dart packages and plugins)
-
Flutter package consumers are interested in searching for packages that work for iOS, or Android, or both.
-
Flutter package developers need to know if they are creating a pure-dart package, or a plugin as the coding requirements are entirely different for each.
- Would be good to have
flutter create --package-- this would not create ios and android subdirs, and main.dart would not have channel code. Support flutter create --package #10377
- Would be good to have
-
Automatically determining what platform a plugin supports is hard; we would need to be able to tell the difference between "empty" template files and actual "coded" files. We are leaning towards making this declarative in
pubspec.yaml. We could combine this with support for listing SDK versions, for example:flutter: plugin: android-support: min-sdk: 16
-
cc @kevmoo
In todays discussion, added the following:
-
When publishing with
flutter packages publish, check that:
a. If publishing a package,androidandiosfolders are not present
b. If publishing a plugin, that does not declare android support,androidfolder is not present
c. If publishing a plugin, that does not declare ios support,iosfolder is not present
d. If publishing a plugin, that declares android support,androidfolder is present
e. If publishing a plugin, that declares ios support,iosfolder is present -
flutter create --plugincreates bothandroidandiosfolders, but placesandroid-supportandios-supportin comments inpubspec.yamlso that the developer is encouraged to make an explicit choice
-
This seems like it fits the pub server 2.0 workstream and the plugin framework maintenance workstream. I'm not sure if this is considered one of our top 5 common user journeys, but I'm going to guess it is. As a result, I'm leaving this in the current milestone.
@mravn-google triaging - any updates?
Postponing to milestone 4.
3 remaining items
To better prepare for the ecosystem scaling to more platforms having a solid way for a plugin to declare its supported platforms is becoming more important.
Below is a proposal for a new schema for declare a plugin's supported platforms which we plan on implementing. Feedback is welcomed.
What are the implications of a plugin saying it supports platformFoo?
- Generated plugin registrants (for “platformFoo”) for applications depending on the plugin will call the plugin’s “registerWith” method(essentially assuming that the plugin provides “platformFoo” code and invoking it)
- Configuration of platform specific package managers(e.g for pulling a dependency needed by the plugin).
- [planned] The pub website considers the plugin as supporting “platformFoo”.
Current state
Currently presence of specific keys in the plugin node(flutter:\n plugin:) in the plugin’s pubspec.yaml file determines whether the flutter tool generates a registerWith invocation in plugin registrants for dependent Flutter applications. Sample pubspec:
flutter: plugin: androidPackage: io.flutter.plugins.sample iosPrefix: FLT macosPrefix: FLT pluginClass: SamplePlugin
- The presence of the androidPackage node determines whether to invoke “registerWith” for the plugin in Android application’s plugin registrant.
- The presence of both pluginClass and macosPrefix determines whether to invoke “registerWith” for the plugin in a macOS application’s plugin registrant.
Issues with current state
- Inconsistent across platforms (and so doesn’t scale well).
- The default plugin template supports Android and iOS
- It’s likely that almost any plugin currently out there whether it really supports Android and iOS
has the nodes to indicate support for both platforms in its pubspec. - This issue is out of scope for the current document, it seems like there’s an agreement that we should go for an opt-in model (when you create a plugin it supports no platforms by default and the author has to specify which platforms to support, and platforms can be easily added after the initial template generation).
- It’s likely that almost any plugin currently out there whether it really supports Android and iOS
- Few people know or treat the presence of androidPackage as a declaration of supporting a platform.
- It’s impossible to declare that iOS isn’t supported.
- It can be inconsistent (e.g specifying macosPrefix without a pluginClass).
Proposal for a new pubspec schema
flutter: plugin: platforms: web: # The structure of the contents are completely arbitrary from Flutter's POV # and are defined by the platform embedder. registrantFile: lib/web.dart registerMethod: registerWith fuchsia: # The structure of the contents are completely arbitrary from Flutter's POV # and are defined by the platform embedder. registrantFile: lib/fuchsia.dart registerMethod: registerWith macos: # The structure of the contents are completely arbitrary from Flutter's POV # and are defined by the platform embedder. classPrefix: FLT pluginClass: SamplePlugin
- The platforms node in plugin’s pubspec.yaml have a single entry for each platform. The key being the platform’s name.
- A presence of a key “foo” under plugin: indicates that the plugin supports platform “foo”.
- Flutter doesn’t enforce any structure on the value of “foo”, and the structure of the contents are completely dependent on the platform’s embedder(whether through flutter tool extension or by hard coded implementation in the flutter tool). The platform’s embedder should validate the contents of the “foo” plugin.
- This means that validating this structure as part of scoring on the pub server can only be done for officially supported platforms.
Officially supported vs non officially supported platforms
It's unclear whether there should be a differentiation between officially supported platforms to none officially supported platforms.
- Can I say my plugin supports xbox in pubspec.yaml?
- Will it show on the pub website?
- What happens when 2 different platform embedders expect the same name to be used in the pubspec?
One potential approach would be for the flutter tool to reserve some namespace for non officially supported platforms (e.g by prepending an
x-prefix), an to enforce that a platform name is whitelisted or is inx-namespace.This is less impactful before flutter tool extensions are supported. For now we are going to start by only allowing whitelisted platform names to be used in pubspec, and we could later make the flutter tool less strict when this becomes a real need.
Dealing with Android/iOS in a backward compatible way
Flutter tool will allow a plugin to either specify a
platforms:\n android key, or to specifyandroidPackage(when building an app). This ensures existing apps keeps working with plugins that have updated to the new mechanism and plugins that haven’t updated.The pub website will treat plugins that specify an androidPackage as supporting android. And all plugins that use the old schema as supporting iOS.
Encouraging plugin authors to migrate to the new schema
We’d want the pub client to only allow publishing plugins that have migrated off the older way of declaring android/ios support.
After some period of launching this new schema, we'd like to reduce to score for plugins that haven't migrated.
Reacted by droplet, Gregory Sech and trietbui85- added a commit that references this issue
on Aug 15, 2019 The new schema proposed above is currently available on master, and we will start some process to encourage migration to it. For plugins that use the new schema pub can rely on the platforms spec pubspec.yaml.
For plugins that use the previous schema we can assume that they support android and iOS and this will be correct most of the times but not always. I'm leaving the decision whether to make this assumption in pub.dev or not to @mit-mit and @csells.
Reacted by dropletThis 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.- locked as resolved and limited conversation to collaborators
on Aug 28, 2021 - addedpackageflutter/packages repository. See also p: labels.flutter/packages repository. See also p: labels.
on Jul 5, 2023
Currently Pub is able to detect that a package is a plugin. But it has no reliable way of detecting if Android, or iOS, or both are supported. Simply checking for the presence of the
androidandiosfolders would be error prone as these are created whenever you runflutter create --plugin.