Skip to content

Latest commit

 

History

80 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FlutterWatch Plugins

Flutter plugins with Apple Watch (watchOS) support, maintained by the flutterwatch.dev organization.

These are companions to flutter-watchos — the Flutter watchOS custom embedder. Most are federated *_watchos implementations of popular pub.dev plugins, produced with the flutter-watchos plugin port tool and finished/verified by hand.

Publishing to pub.dev under the flutterwatch.dev publisher is in progress. Each version badge below lights up automatically once its package is published; until then, add the package as a git dependency (see Usage).

How watchOS plugins work

watchOS plugins ship native code via dart:ffi: the package exports C symbols from watchos/Classes/*.m, declares them under flutter.plugin.platforms.watchos.ffiSymbols, and the flutter-watchos CLI statically links them into the watch binary where Dart resolves them with DynamicLibrary.process(). A plugin can additionally ship native SwiftUI platform views (watchos/Views/*.swift) that the CLI compiles into the app and the plugin embeds with WatchPlatformView (package:flutter_watchos) — see video_player_watchos. Method-channel plugins are not supported on watchOS — a package whose watchos: block declares only pluginClass: will build but its channel calls throw MissingPluginException (the CLI warns about this at build time).

Companion apps: talking to the iPhone

One package here is not a port of an upstream plugin, because there is no upstream to port: WatchConnectivity is the only transport Apple provides between a watch and its phone, and it needs an implementation on both sides.

Plugin What it is Backend
flutter_watch_link First-party. One Dart API for phone↔watch messaging, application context, and guaranteed transfers — the same code on both devices. WCSession (one FFI implementation, compiled for both)

Upstream watch_connectivity is phone-side only, and its "platform interface" is explicitly not a federated one — there is no instance hook to implement — so a *_watchos implementation of it is not possible. It also has no transferUserInfo, which is the tier a companion app needs when the counterpart is asleep.

See its example/ for a worked companion app — one main.dart, running on both devices.

List of plugins

Every plugin below has a working watchOS implementation, verified on the watch simulator. Full details (API coverage, watchOS capability, and porting notes) are in each package's README.md and PORTING_REPORT.md.

Plugin Upstream watchOS backend
path_provider_watchos pub path_provider NSSearchPathForDirectoriesInDomains
shared_preferences_watchos pub shared_preferences NSUserDefaults
package_info_plus_watchos pub package_info_plus NSBundle
device_info_plus_watchos pub device_info_plus WKInterfaceDevice
url_launcher_watchos pub url_launcher ASWebAuthenticationSession (web pages on the watch), WKApplication.openSystemURL (tel:/sms:), NSUserActivity Handoff (web, externalApplication)
battery_plus_watchos pub battery_plus WKInterfaceDevice battery
connectivity_plus_watchos pub connectivity_plus nw_path_monitor
flutter_secure_storage_watchos pub flutter_secure_storage Keychain (SecItem*)
network_info_plus_watchos pub network_info_plus getifaddrs (IP; no SSID)
sensors_plus_watchos pub sensors_plus CoreMotion (CMMotionManager)
local_auth_watchos pub local_auth LocalAuthentication (passcode)
geolocator_watchos pub geolocator CoreLocation (CLLocationManager)
video_player_watchos pub video_player AVFoundation + AVKit platform view
audioplayers_watchos pub audioplayers AVFoundation (AVPlayer)
in_app_purchase_watchos pub in_app_purchase StoreKit (SKProductsRequest, SKPaymentQueue)
games_services_watchos pub games_services GameKit (GKLeaderboard, GKLocalPlayer) — leaderboards only †
firebase_core_watchos pub firebase_core Firebase Apple SDK (FirebaseCore)
firebase_auth_watchos pub firebase_auth Firebase Apple SDK (FirebaseAuth)
firebase_storage_watchos pub firebase_storage Firebase Apple SDK (FirebaseStorage)
firebase_messaging_watchos pub firebase_messaging Firebase Apple SDK (FirebaseMessaging)

† games_services_watchos is staged at 0.0.1. Sign-in and score submission have been observed working on a physical Apple Watch; reading leaderboard entries has not — GKLocalPlayer reports an authenticated player with an unresolved alias and GameKit then refuses the read. The app under test was side-loaded rather than installed through its companion, which is the leading suspect. See its PORTING_REPORT.md.

First-party watch capabilities (platform detection, device info, haptics, Digital Crown) ship in flutter_watchos itself — check there before adding a plugin.

Evaluated but not provided

These upstream plugins' core capability does not exist on watchOS, so a published package would be misleading:

Plugin Why not on watchOS
webview_flutter No WebKit in the watchOS SDK, so no embeddable web view; a page can only be shown as a full-screen system sheet, which url_launcher_watchos does
google_sign_in No GoogleSignIn watchOS SDK; sign-in is delegated to the paired iPhone
image_picker No camera and no photo-picker UI on the watch
google_maps_flutter No Google Maps SDK for watchOS (an Apple MapKit backend would not honestly implement the interface)

Note the difference from tvOS: CoreLocation, HealthKit, CoreMotion, StoreKit purchasing, and (watchOS 9+) LocalAuthentication all exist on the watch — plugins built on those are portable, not excluded.

Feasible but not yet ported

These have a watchOS-viable native backend and are good future additions; they are simply out of scope for now (large surface or partial support): sqflite (SQLite), flutter_tts (AVFoundation), wakelock_plus (only a session-typed WKExtendedRuntimeSession, not a general idle-timer disable), and cloud_firestore (the Firebase Apple SDK ships Firestore's core as a prebuilt binary with no watchOS slice, so a port needs Firebase's from-source Firestore build; the rest of the network-viable Firebase family — core, auth, storage, messaging — is ported above).

Usage

The upstream plugins do not endorse a watchOS implementation, so add the *_watchos package to your app explicitly, alongside the upstream plugin:

dependencies:
  path_provider: ^2.1.0
  path_provider_watchos: ^0.0.1

The version badges in the table above are the current published versions — use those, since these packages are still pre-1.0 and a caret constraint on 0.x is narrower than you may expect.

Then use the upstream plugin's API exactly as on iOS — the *_watchos implementation registers automatically via Flutter's federated plugin runner, with no imports or client code changes.

flutter_watch_link is the exception: it is not on pub.dev yet, so depend on it via git.

dependencies:
  flutter_watch_link:
    git:
      url: https://github.com/flutterwatch/plugins.git
      path: packages/flutter_watch_link

A few packages need a writable directory and therefore also path_provider_watchos: e.g. video_player_watchos (for VideoPlayerController.file). Their READMEs note this.

Examples & tests

Each package ships the upstream plugin's own example (its demo lib/ and its official integration_test/) ported verbatim by flutter-watchos plugin port --include-example with a watchOS runner on top, plus a host-side unit test. The examples and tests are unmodified — the example imports only the app-facing plugin, and the *_watchos implementation registers federatedly with no client code changes. Each is verified on the watch simulator:

cd packages/<plugin>_watchos/example
flutter-watchos drive \
  --driver=test_driver/integration_test.dart \
  --target=integration_test/<test-file> -d <watch-sim>

The official integration tests pass on the watch for path_provider, network_info_plus, sensors_plus, local_auth, device_info_plus, battery_plus, connectivity_plus, shared_preferences (64/64), in_app_purchase, and package_info_plus's plugin-level fromPlatform case — some cases self-skip on non-Android, as upstream intends. Two upstream tests are written as phone-UI sweeps that pump the demo's scrolling list and find widgets that a ~200 px watch screen never materialises: package_info_plus's example test and flutter_secure_storage's page-object app_test. Those fail on the watch for viewport reasons, not plugin defects — the FFI implementations are proven by the plugin-level cases, the host unit tests, and the unified demo. geolocator's upstream example has no integration_test/ (its Baseflow demo is manual), so that package is verified by building and running the example on the sim. in_app_purchase_watchos additionally ships a purchase_test covering the full StoreKit round trip (buy → purchaseStream → completePurchase); it needs StoreKit testing, which only an Xcode launch activates, so a CLI run skips its product assertions rather than failing — see that package's README.

Where an official test surfaced a genuine behavioural gap, the fix went into the implementation, not the test — e.g. shared_preferences_watchos now throws TypeError on a wrong-typed read (matching every other platform), and package_info_plus_watchos now returns installerStore / installTime / updateTime natively.

How this repository was created

These packages were not hand-written from scratch. Each was generated with the flutter-watchos plugin port tool (part of flutter-watchos) and then verified — and where needed finished — by hand.

1. Port an upstream plugin

flutter-watchos plugin port takes an existing Apple plugin (the iOS implementation package) and emits a federated *_watchos FFI scaffold.

# from a published pub.dev package (what we used):
flutter-watchos plugin port --from-pub shared_preferences_foundation \
  --output packages/shared_preferences_watchos --include-example

# or from git, or from a local path:
flutter-watchos plugin port --from-git https://github.com/foo/bar.git --ref main --output ...
flutter-watchos plugin port ../some_plugin_ios --output ...

The exact upstream source for each package is recorded at the top of its PORTING_REPORT.md (e.g. video_player_watchos ← video_player_avfoundation, shared_preferences_watchos ← shared_preferences_foundation, audioplayers_watchos ← audioplayers_darwin).

What the porter does automatically: lays out the federated package (pubspec, lib/, watchos/, analysis_options.yaml, LICENSE, CHANGELOG.md), federates through the upstream *_platform_interface, emits an FFI header/.m scaffold with the C-symbol declarations wired into flutter.plugin.platforms.watchos.ffiSymbols, generates a PORTING_REPORT.md recording the source, the watchOS capability outlook (driven by a watchOS API-availability database), and a checklist, and — with --include-example — ports the upstream example app and its official integration_test/ verbatim under a watchOS runner.

2. Read the porting report

Every package gets a PORTING_REPORT.md: the source + version, the watchOS capability outlook, the FFI surface, every unsupported region with the reason, and a ## Verification status table. Read it before trusting a port.

3. Implement the native FFI, then verify

The porter emits a scaffold, not a working backend (by design — the native .m functions are stubs). The real native implementation is written by hand against the platform interface, following AUTHORING.md and path_provider_watchos as the reference. A package only joins the list once it is green:

cd packages/<plugin>_watchos/example
flutter-watchos build watchos --simulator --debug          # must be green
cd ..
flutter-watchos test                                        # host unit tests
cd example
flutter-watchos drive \
  --driver=test_driver/integration_test.dart \
  --target=integration_test/<test-file> -d <watch-sim>      # real native code on-sim

4. Curate

Packages whose primary purpose can't work on watchOS are not shipped — they are documented under Evaluated but not provided rather than published broken.

See AUTHORING.md for the deeper per-plugin recipe.

Repository layout

plugins/
├── packages/<plugin>_watchos/    # one directory per plugin
│   ├── lib/                      # Dart (federated impl + FFI bindings)
│   ├── watchos/Classes/          # native FFI (Objective-C, exported C symbols)
│   ├── watchos/Views/            # native SwiftUI platform views (optional)
│   ├── watchos/Package.swift     # SwiftPM manifest
│   ├── example/                  # upstream example + integration_test, verbatim
│   ├── test/                     # host-side unit tests (FFI bindings faked)
│   ├── PORTING_REPORT.md         # port detail + verification-status table
│   ├── README.md  CHANGELOG.md  LICENSE
└── AUTHORING.md                  # how to add a new one

Contributing

  • Federate via the upstream *_platform_interface; suffix _watchos.
  • Ship native code as dart:ffi exported C symbols; method-channel pluginClass:-only plugins are inert on watchOS.
  • Guard watchOS-unsupported APIs and document them in the package README.md and PORTING_REPORT.md so users can assess compatibility.
  • Add host-side unit tests and, where the upstream has one, its official integration_test/ verbatim — fix gaps in the implementation, never the test.
  • A package only ships if it builds green and verifies on the watch simulator.

License

BSD-3-Clause — see LICENSE. Ported packages retain their upstream copyright; watchOS additions are © The FlutterWatch Authors.

About

watchOS implementations of popular Flutter plugins, for flutter-watchos. 13 federated FFI packages.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages