---
description: Capacitor Watch plugin to exchange messages, user info, and state between your app and Apple Watch and Wear OS companion apps.
title: Capacitor Watch Plugin for Android & iOS - Capawesome
image: https://capawesome.io/docs/assets/images/social/sdks/capacitor/watch.png
---

<!doctype html> 

[Skip to content ](#capacitor-watch-plugin) 

[📲 Introducing **Build Sharing** — get your builds onto testers' devices with a link & QR code. No account required. ](/blog/share-mobile-app-builds-with-testers/) 

* [ SDKs ](/docs/sdks/)
* [ Formbricks ](/docs/sdks/capacitor/formbricks/)
* [ Geocoder ](/docs/sdks/capacitor/geocoder/)
* [ Geofences ](/docs/sdks/capacitor/geofences/)
* [ Google Sign-In ](/docs/sdks/capacitor/google-sign-in/)
* [ Grafana Faro ](/docs/sdks/capacitor/grafana-faro/)
* [ Gyroscope ](/docs/sdks/capacitor/gyroscope/)
* [ Haptics ](/docs/sdks/capacitor/haptics/)
* [ Health ](/docs/sdks/capacitor/health/)
* [ Home Indicator ](/docs/sdks/capacitor/home-indicator/)
* [ In-App Browser ](/docs/sdks/capacitor/in-app-browser/)
* [ Install Referrer ](/docs/sdks/capacitor/install-referrer/)
* [ Intercom ](/docs/sdks/capacitor/intercom/)
* [ Intune ](/docs/sdks/capacitor/intune/)
* [ Keep Awake ](/docs/sdks/capacitor/keep-awake/)
* [ libSQL ](/docs/sdks/capacitor/libsql/)
* [ Light Sensor ](/docs/sdks/capacitor/light-sensor/)
* [ Live Update ](/docs/sdks/capacitor/live-update/)
* [ LLM ](/docs/sdks/capacitor/llm/)
* [ Localization ](/docs/sdks/capacitor/localization/)
* [ Mail Composer ](/docs/sdks/capacitor/mail-composer/)
* [ Managed Configurations ](/docs/sdks/capacitor/managed-configurations/)
* [ MapLibre ](/docs/sdks/capacitor/maplibre/)
* [ Maps Launcher ](/docs/sdks/capacitor/maps-launcher/)
* [ Media Session ](/docs/sdks/capacitor/media-session/)
* [ ML Kit ](/docs/sdks/capacitor/mlkit/)
* [ Navigation Bar ](/docs/sdks/capacitor/navigation-bar/)
* [ Network ](/docs/sdks/capacitor/network/)
* [ NFC ](/docs/sdks/capacitor/nfc/)
* [ Node.js ](/docs/sdks/capacitor/nodejs/)
* [ OAuth ](/docs/sdks/capacitor/oauth/)
* [ Passkeys ](/docs/sdks/capacitor/passkeys/)
* [ Password Autofill ](/docs/sdks/capacitor/password-autofill/)
* [ PDF Generator ](/docs/sdks/capacitor/pdf-generator/)
* [ PDF Viewer ](/docs/sdks/capacitor/pdf-viewer/)
* [ Pedometer ](/docs/sdks/capacitor/pedometer/)
* [ Permissions ](/docs/sdks/capacitor/permissions/)
* [ Phone Dialer ](/docs/sdks/capacitor/phone-dialer/)
* [ Photo Editor ](/docs/sdks/capacitor/photo-editor/)
* [ Photo Manipulator ](/docs/sdks/capacitor/photo-manipulator/)
* [ PixLive ](/docs/sdks/capacitor/pixlive/)
* [ PostHog ](/docs/sdks/capacitor/posthog/)
* [ Printer ](/docs/sdks/capacitor/printer/)
* [ Privacy Screen ](/docs/sdks/capacitor/privacy-screen/)
* [ Proximity Sensor ](/docs/sdks/capacitor/proximity-sensor/)
* [ Purchases ](/docs/sdks/capacitor/purchases/)
* [ RealtimeKit ](/docs/sdks/capacitor/realtimekit/)
* [ Root Detection ](/docs/sdks/capacitor/root-detection/)
* [ Screen Brightness ](/docs/sdks/capacitor/screen-brightness/)
* [ Screen Orientation ](/docs/sdks/capacitor/screen-orientation/)
* [ Screen Reader ](/docs/sdks/capacitor/screen-reader/)
* [ Screenshot ](/docs/sdks/capacitor/screenshot/)
* [ Secure Preferences ](/docs/sdks/capacitor/secure-preferences/)
* [ Settings Launcher ](/docs/sdks/capacitor/settings-launcher/)
* [ Shake ](/docs/sdks/capacitor/shake/)
* [ Silent Mode ](/docs/sdks/capacitor/silent-mode/)
* [ SIM ](/docs/sdks/capacitor/sim/)
* [ SMS Composer ](/docs/sdks/capacitor/sms-composer/)
* [ Speech Recognition ](/docs/sdks/capacitor/speech-recognition/)
* [ Speech Synthesis ](/docs/sdks/capacitor/speech-synthesis/)
* [ Share Target ](/docs/sdks/capacitor/share-target/)
* [ Square Mobile Payments ](/docs/sdks/capacitor/square-mobile-payments/)
* [ SQLite ](/docs/sdks/capacitor/sqlite/)
* [ Superwall ](/docs/sdks/capacitor/superwall/)
* [ System WebView ](/docs/sdks/capacitor/system-webview/)
* [ Tauri ](/docs/sdks/capacitor/tauri/)
* [ Text Interaction ](/docs/sdks/capacitor/text-interaction/)
* [ Text Zoom ](/docs/sdks/capacitor/text-zoom/)
* [ Thermal State ](/docs/sdks/capacitor/thermal-state/)
* [ Toast ](/docs/sdks/capacitor/toast/)
* [ Torch ](/docs/sdks/capacitor/torch/)
* [ Vault ](/docs/sdks/capacitor/vault/)
* [ Volume ](/docs/sdks/capacitor/volume/)
* [ Wallet ](/docs/sdks/capacitor/wallet/)
* Watch [ Watch ](/docs/sdks/capacitor/watch/)
* [ iOS ](#ios)
* [ watchOS ](#watchos)
* [ Wear OS ](#wear-os)
* [ Configuration ](#configuration)
* [ Usage ](#usage)
* [ API ](#api)
* [ Communication Channels ](#communication-channels)
* [ Platform Behavior ](#platform-behavior)
* [ FAQ ](#faq)
* [ Related Plugins ](#related-plugins)
* [ Newsletter ](#newsletter)
* [ Changelog ](#changelog)
* [ Breaking Changes ](#breaking-changes)
* [ License ](#license)
* [ Wifi ](/docs/sdks/capacitor/wifi/)
* [ YouTube Player ](/docs/sdks/capacitor/youtube-player/)
* [ Zip ](/docs/sdks/capacitor/zip/)
* [ Cordova ](/docs/sdks/cordova/)
* [ Cloud ](/docs/cloud/)
* [ Integrations ](/docs/cloud/live-updates/integrations/)
* Concepts
* Reference
* [ Troubleshooting ](/docs/cloud/live-updates/troubleshooting/)
* [ FAQ ](/docs/cloud/live-updates/faq/)
* [ Native Builds ](/docs/cloud/native-builds/)
* [ Set Up Environments ](/docs/cloud/native-builds/environments/)
* [ Set Up Native Configurations ](/docs/cloud/native-builds/native-configurations/)
* [ Auto-Increment Build Numbers ](/docs/cloud/native-builds/auto-incrementing-build-numbers/)
* [ Configure the Web Build Script ](/docs/cloud/native-builds/web-build-script/)
* [ Build from a Monorepo ](/docs/cloud/native-builds/monorepo/)
* [ Use pnpm, Yarn, or bun ](/docs/cloud/native-builds/package-managers/)
* [ Install Private npm Packages ](/docs/cloud/native-builds/npm-private-registry/)
* [ Override the Java Version ](/docs/cloud/native-builds/override-java-version/)
* [ Custom iOS Provisioning Profiles ](/docs/cloud/native-builds/custom-ios-provisioning-profiles/)
* [ Build without Git ](/docs/cloud/native-builds/build-without-git/)
* [ Access Git Behind a Firewall ](/docs/cloud/native-builds/firewall-access/)
* [ Integrations ](/docs/cloud/native-builds/integrations/)
* Reference
* [ Troubleshooting ](/docs/cloud/native-builds/troubleshooting/)
* [ FAQ ](/docs/cloud/native-builds/faq/)
* [ App Store Publishing ](/docs/cloud/app-store-publishing/)
* [ Submit a Build ](/docs/cloud/app-store-publishing/submit-a-build/)
* [ Submit Automatically After a Build ](/docs/cloud/app-store-publishing/submit-automatically/)
* [ Troubleshooting ](/docs/cloud/app-store-publishing/troubleshooting/)
* [ FAQ ](/docs/cloud/app-store-publishing/faq/)
* [ Automations ](/docs/cloud/automations/)
* [ Reference ](/docs/cloud/automations/reference/)
* [ Troubleshooting ](/docs/cloud/automations/troubleshooting/)
* [ FAQ ](/docs/cloud/automations/faq/)
* [ Assist ](/docs/cloud/assist/)
* [ CLI ](/docs/cloud/cli/)
* APIs and SDKs
* [ Webhooks ](/docs/cloud/webhooks/)
* [ Integrations ](/docs/cloud/integrations/)
* Notifications
* Account
* [ Organization ](/docs/cloud/organizations/)
* [ Two-Factor Enforcement ](/docs/cloud/organizations/two-factor-authentication/)
* [ Network Restrictions ](/docs/cloud/organizations/network-restrictions/)
* [ Audit Logs ](/docs/cloud/organizations/audit-logs/)
* [ Billing ](/docs/cloud/organizations/billing/)
* [ License Keys ](/docs/cloud/license-keys/)
* [ AI ](/docs/ai/)
* [ Insiders ](/docs/insiders/)
* [ Billing & Plans ](/docs/insiders/billing-and-plans/)
* [ FAQ ](/docs/insiders/faq/)
* [ License ](https://capawesome.io/legal/eula/)
* [ Support ](/docs/support/)
* [ Contributing ](/docs/contributing/)
* Contributing code
* [ Code of Conduct ](/docs/contributing/code-of-conduct/)
* [ Questions ](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion#creating-a-discussion)
* [ Blog ](/blog/)
* Categories

* [ iOS ](#ios)
* [ watchOS ](#watchos)
* [ Wear OS ](#wear-os)
* [ Configuration ](#configuration)
* [ Usage ](#usage)
* [ API ](#api)
* [ Communication Channels ](#communication-channels)
* [ Platform Behavior ](#platform-behavior)
* [ FAQ ](#faq)
* [ Related Plugins ](#related-plugins)
* [ Newsletter ](#newsletter)
* [ Changelog ](#changelog)
* [ Breaking Changes ](#breaking-changes)
* [ License ](#license)

Build and Ship Mobile Apps Faster

Cloud builds, OTA live updates, and automated store releases — everything your mobile team needs in one platform.

[Start for free ](https://console.cloud.capawesome.io/?utm%5Fsource=docs&utm%5Fmedium=sidebar%5Fcta&utm%5Fcampaign=docs%5Fcta) [See our plans ](https://capawesome.io/pricing/?utm%5Fsource=docs&utm%5Fmedium=sidebar%5Fcta&utm%5Fcampaign=docs%5Fcta) 

# Capacitor Watch Plugin[¶](#capacitor-watch-plugin "Permanent link")

Capacitor plugin for communicating with Apple Watch and Wear OS apps. Send messages, sync state and queue transfers between your Capacitor app and your native watch app with a single, unified API.

[ ![Deliver Live Updates to your Capacitor app with Capawesome Cloud](../../../assets/external/cloud.capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.69628c3f.png) ](https://cloud.capawesome.io/) 

## Features[¶](#features "Permanent link")

The Capacitor Watch plugin is a communication bridge between your Capacitor app and your native watch app. You build your watch UI natively (SwiftUI on watchOS, whatever you prefer on Wear OS) and use this plugin to exchange data with it. Here are some of the key features:

* 💬 **Messaging**: Send live messages with optional request/reply semantics.
* 🔄 **State Sync**: Share the latest state between phone and watch, even across app restarts.
* 📦 **Queued Transfers**: Queue data for guaranteed delivery, even if the watch is currently not reachable.
* 📡 **Reachability**: Query the connection info and get notified when the reachability changes.
* 🌙 **Background Reception**: Data received while the app is closed is replayed as soon as your listeners are registered. On Android, the data is persisted and even survives an app restart.
* ⌚ **Watch SDKs**: Ships with native SDKs for watchOS (Swift Package) and Wear OS (Kotlin library) for the watch side.
* 🧩 **Zero Boilerplate**: No `AppDelegate` or `MainActivity` modifications required.
* 🤝 **Compatibility**: Works hand in hand with the [Health](https://capawesome.io/docs/sdks/capacitor/health/) and [Background Geolocation](https://capawesome.io/docs/sdks/capacitor/background-geolocation/) plugins.
* 📦 **CocoaPods & SPM**: Supports CocoaPods and Swift Package Manager for iOS.
* 🔁 **Up-to-date**: Always supports the latest Capacitor version.
* ⭐️ **Support**: Priority support from the Capawesome Team.
* ✨ **Handcrafted**: Built from the ground up with care and expertise, not forked or AI-generated.

Missing a feature? Just [open an issue](https://github.com/capawesome-team/capacitor-plugins/issues) and we'll take a look!

## Use Cases[¶](#use-cases "Permanent link")

The Watch plugin is typically used whenever an app wants to extend its experience to the wrist, for example:

* **Fitness and health**: Start and stop workouts from the watch and mirror live stats from the phone.
* **Remote control**: Control media playback, smart home devices or timers from the watch.
* **Glanceable data**: Keep the latest scores, tasks or account balances in sync with the watch app.
* **Quick actions**: Confirm orders, check in or trigger phone-side actions with a tap on the watch.

## Compatibility[¶](#compatibility "Permanent link")

| Plugin Version | Capacitor Version | Status         |
| -------------- | ----------------- | -------------- |
| 0.x.x          | \>=8.x.x          | Active support |

## Installation[¶](#installation "Permanent link")

This plugin is only available to [Capawesome Insiders](https://capawesome.io/insiders/). First, make sure you have the Capawesome npm registry set up. You can do this by running the following commands:

`[](#%5F%5Fcodelineno-0-1)npm config set @capawesome-team:registry https://npm.registry.capawesome.io
[](#%5F%5Fcodelineno-0-2)npm config set //npm.registry.capawesome.io/:_authToken <YOUR_LICENSE_KEY>
`

**Attention**: Replace `<YOUR_LICENSE_KEY>` with the license key you received from Polar. If you don't have a license key yet, you can get one by becoming a [Capawesome Insider](https://capawesome.io/insiders/).

Next, you can use our **AI-Assisted Setup** to install the plugin. Add the [Capawesome Skills](https://github.com/capawesome-team/skills) to your AI tool using the following command:

`[](#%5F%5Fcodelineno-1-1)npx skills add capawesome-team/skills --skill capacitor-plugins
`

Then use the following prompt:

`` [](#%5F%5Fcodelineno-2-1)Use the `capacitor-plugins` skill from `capawesome-team/skills` to install the `@capawesome-team/capacitor-watch` plugin in my project.
 ``

If you prefer **Manual Setup**, install the plugin by running the following commands and follow the platform-specific instructions below:

`[](#%5F%5Fcodelineno-3-1)npm install @capawesome-team/capacitor-watch
[](#%5F%5Fcodelineno-3-2)npx cap sync
`

### Android[¶](#android "Permanent link")

The plugin registers a `WearableListenerService` in its own manifest, so messages and data from the watch are received even while your app is closed. No manifest changes are required.

This plugin requires Google Play services. On devices without Google Play services, all plugin methods reject as unavailable.

#### Proguard[¶](#proguard "Permanent link")

If you are using Proguard, you need to add the following rules to your `proguard-rules.pro` file:

`[](#%5F%5Fcodelineno-4-1)-keep class io.capawesome.capacitorjs.plugins.** { *; }
`

#### Variables[¶](#variables "Permanent link")

If needed, you can define the following project variable in your app’s `variables.gradle` file to change the default version of the dependency:

* `$playServicesWearableVersion` version of `com.google.android.gms:play-services-wearable` (default: `20.0.1`)

This can be useful if you encounter dependency conflicts with other plugins in your project.

### iOS[¶](#ios "Permanent link")

No additional steps are required for the phone side. The plugin activates the `WCSession` automatically when it is loaded, so you do **not** need to modify your `AppDelegate`.

This plugin is the phone side of the bridge. To exchange data, you also need a native watch app. The plugin ships with watch-side SDKs for both platforms, so the watch side is just as simple.

### watchOS[¶](#watchos "Permanent link")

The watchOS SDK is a Swift Package located at `node_modules/@capawesome-team/capacitor-watch/sdks/watchos`. It wires up the `WCSession` for you and exposes an `ObservableObject` that you can use directly in SwiftUI.

Follow these steps to add a watch app to your Capacitor project:

1. Open your app's Xcode project (`ios/App/App.xcodeproj`) — or the Xcode workspace (`ios/App/App.xcworkspace`) if your app uses CocoaPods.
2. Select **File > New > Target…**, choose the **watchOS** tab and select the **Watch App for Existing iOS App** template.
3. If no companion app is selectable, make sure you opened the dialog via **File > New > Target…** (not **File > New > Project…**) and that the **Project** dropdown at the bottom of the dialog points to your app's project.
4. Enter a product name (e.g. `watch`) and select **SwiftUI** as interface. The bundle identifier of the watch app must be prefixed with the bundle identifier of your iOS app (e.g. `com.example.app.watchkitapp`), which Xcode derives automatically.
5. Select **File > Add Package Dependencies… > Add Local…** and select the `node_modules/@capawesome-team/capacitor-watch/sdks/watchos` folder. Add the `CapawesomeWatchSDK` product to your **watch app target** (not the iOS app target).
6. Activate the session and start communicating:

`[](#%5F%5Fcodelineno-5-1)import SwiftUI
[](#%5F%5Fcodelineno-5-2)import CapawesomeWatchSDK
[](#%5F%5Fcodelineno-5-3)
[](#%5F%5Fcodelineno-5-4)struct ContentView: View {
[](#%5F%5Fcodelineno-5-5)    @ObservedObject private var watch = CapawesomeWatch.shared
[](#%5F%5Fcodelineno-5-6)
[](#%5F%5Fcodelineno-5-7)    var body: some View {
[](#%5F%5Fcodelineno-5-8)        VStack {
[](#%5F%5Fcodelineno-5-9)            Text(watch.reachable ? "Reachable" : "Not reachable")
[](#%5F%5Fcodelineno-5-10)            Button("Send Message") {
[](#%5F%5Fcodelineno-5-11)                watch.sendMessage(["text": "Hello from the watch!"])
[](#%5F%5Fcodelineno-5-12)            }
[](#%5F%5Fcodelineno-5-13)        }
[](#%5F%5Fcodelineno-5-14)        .onAppear {
[](#%5F%5Fcodelineno-5-15)            watch.onMessageReceived = { data, reply in
[](#%5F%5Fcodelineno-5-16)                print("Message received:", data)
[](#%5F%5Fcodelineno-5-17)                reply?(["text": "Hello back!"])
[](#%5F%5Fcodelineno-5-18)            }
[](#%5F%5Fcodelineno-5-19)            watch.activate()
[](#%5F%5Fcodelineno-5-20)        }
[](#%5F%5Fcodelineno-5-21)    }
[](#%5F%5Fcodelineno-5-22)}
`

You can find a complete minimal watch app in the [example/watchos](https://github.com/capawesome-team/capacitor-plugins/tree/main/packages/watch/example/watchos) folder. When adding these files to your watch app target, enable **Copy items if needed**, select only the watch app as target and do not create a bridging header (the sources are pure Swift).

**Note**: The local package reference is resolved relative to your Xcode project. Make sure `node_modules` is installed before opening the project.

### Wear OS[¶](#wear-os "Permanent link")

The Wear OS SDK is a Kotlin library located at `node_modules/@capawesome-team/capacitor-watch/sdks/wearos`. It provides send helpers and a listener service base class for the watch side.

Wear OS communication has two hard requirements imposed by the Google Play services Data Layer:

* The Wear OS module must use the **same `applicationId`** as your phone app.
* Both apps must be signed with the **same signing certificate**.

Follow these steps to add a Wear OS app to your Capacitor project:

1. Create a new module folder `android/wear` for the watch app. You can copy the minimal example from the [example/wearos](https://github.com/capawesome-team/capacitor-plugins/tree/main/packages/watch/example/wearos) folder as a starting point (make sure to change the `applicationId` to your app's id).
2. Include the watch app module and the Wear OS SDK in your `android/settings.gradle` file:

`[](#%5F%5Fcodelineno-6-1)include ':wear'
[](#%5F%5Fcodelineno-6-2)include ':capawesome-watch-sdk'
[](#%5F%5Fcodelineno-6-3)project(':capawesome-watch-sdk').projectDir = new File('../node_modules/@capawesome-team/capacitor-watch/sdks/wearos')
`

1. Add the SDK as a dependency to your `android/wear/build.gradle` file:

`[](#%5F%5Fcodelineno-7-1)dependencies {
[](#%5F%5Fcodelineno-7-2)    implementation project(':capawesome-watch-sdk')
[](#%5F%5Fcodelineno-7-3)}
`

1. Declare the capability that the phone side uses to discover your watch app in `android/wear/src/main/res/values/wear.xml`:

`[](#%5F%5Fcodelineno-8-1)<resources>
[](#%5F%5Fcodelineno-8-2)    <string-array name="android_wear_capabilities">
[](#%5F%5Fcodelineno-8-3)        <item>capawesome_watch</item>
[](#%5F%5Fcodelineno-8-4)    </string-array>
[](#%5F%5Fcodelineno-8-5)</resources>
`

1. Create a listener service by extending the `WatchListenerService` base class:

`[](#%5F%5Fcodelineno-9-1)class MyWatchListenerService : WatchListenerService() {
[](#%5F%5Fcodelineno-9-2)    override fun onMessageReceived(data: JSONObject, reply: ((JSONObject) -> Unit)?) {
[](#%5F%5Fcodelineno-9-3)        reply?.invoke(JSONObject().put("text", "Hello back!"))
[](#%5F%5Fcodelineno-9-4)    }
[](#%5F%5Fcodelineno-9-5)
[](#%5F%5Fcodelineno-9-6)    override fun onStateReceived(data: JSONObject) {}
[](#%5F%5Fcodelineno-9-7)
[](#%5F%5Fcodelineno-9-8)    override fun onUserInfoReceived(data: JSONObject) {}
[](#%5F%5Fcodelineno-9-9)}
`

1. Register the service in the manifest of your watch app:

`[](#%5F%5Fcodelineno-10-1)<service
[](#%5F%5Fcodelineno-10-2)    android:name=".MyWatchListenerService"
[](#%5F%5Fcodelineno-10-3)    android:exported="true">
[](#%5F%5Fcodelineno-10-4)    <intent-filter>
[](#%5F%5Fcodelineno-10-5)        <action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
[](#%5F%5Fcodelineno-10-6)        <action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
[](#%5F%5Fcodelineno-10-7)        <data
[](#%5F%5Fcodelineno-10-8)            android:scheme="wear"
[](#%5F%5Fcodelineno-10-9)            android:host="*"
[](#%5F%5Fcodelineno-10-10)            android:pathPrefix="/capawesome/watch" />
[](#%5F%5Fcodelineno-10-11)    </intent-filter>
[](#%5F%5Fcodelineno-10-12)</service>
`

1. Send data to the phone using the `CapawesomeWatch` class. All methods are `suspend` functions, so they must be called from a coroutine:

`[](#%5F%5Fcodelineno-11-1)val watch = CapawesomeWatch(context)
[](#%5F%5Fcodelineno-11-2)val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
[](#%5F%5Fcodelineno-11-3)
[](#%5F%5Fcodelineno-11-4)scope.launch {
[](#%5F%5Fcodelineno-11-5)    watch.sendMessage(JSONObject().put("text", "Hello from the watch!"))
[](#%5F%5Fcodelineno-11-6)    val reply = watch.sendMessageForReply(JSONObject().put("text", "Hello from the watch!"))
[](#%5F%5Fcodelineno-11-7)    watch.updateState(JSONObject().put("counter", 42))
[](#%5F%5Fcodelineno-11-8)    watch.transferUserInfo(JSONObject().put("sentAt", System.currentTimeMillis()))
[](#%5F%5Fcodelineno-11-9)}
`

## Configuration[¶](#configuration "Permanent link")

On Android, the plugin discovers your watch app via the capability that the watch app declares (see the Wear OS setup above). You can configure the capability string in your `capacitor.config.ts` file:

`[](#%5F%5Fcodelineno-12-1)import { CapacitorConfig } from '@capacitor/cli';
[](#%5F%5Fcodelineno-12-2)
[](#%5F%5Fcodelineno-12-3)const config: CapacitorConfig = {
[](#%5F%5Fcodelineno-12-4)  plugins: {
[](#%5F%5Fcodelineno-12-5)    Watch: {
[](#%5F%5Fcodelineno-12-6)      capability: 'capawesome_watch',
[](#%5F%5Fcodelineno-12-7)    },
[](#%5F%5Fcodelineno-12-8)  },
[](#%5F%5Fcodelineno-12-9)};
[](#%5F%5Fcodelineno-12-10)
[](#%5F%5Fcodelineno-12-11)export default config;
`

* `capability` (string): The capability that the Wear OS watch app declares. Only available on Android. Default: `capawesome_watch`.

On iOS, no configuration is required.

## Usage[¶](#usage "Permanent link")

The plugin exposes three communication channels with different delivery guarantees — see [Communication Channels](#communication-channels) for how they map to the platform APIs.

`[](#%5F%5Fcodelineno-13-1)import { Watch } from '@capawesome-team/capacitor-watch';
[](#%5F%5Fcodelineno-13-2)
[](#%5F%5Fcodelineno-13-3)const getConnectionInfo = async () => {
[](#%5F%5Fcodelineno-13-4)  const { reachable, paired, watchAppInstalled } = await Watch.getConnectionInfo();
[](#%5F%5Fcodelineno-13-5)  return { reachable, paired, watchAppInstalled };
[](#%5F%5Fcodelineno-13-6)};
[](#%5F%5Fcodelineno-13-7)
[](#%5F%5Fcodelineno-13-8)const sendMessage = async () => {
[](#%5F%5Fcodelineno-13-9)  await Watch.sendMessage({ data: { text: 'Hello from the phone!' } });
[](#%5F%5Fcodelineno-13-10)};
[](#%5F%5Fcodelineno-13-11)
[](#%5F%5Fcodelineno-13-12)const sendMessageWithReply = async () => {
[](#%5F%5Fcodelineno-13-13)  const { reply } = await Watch.sendMessage({
[](#%5F%5Fcodelineno-13-14)    data: { text: 'Hello from the phone!' },
[](#%5F%5Fcodelineno-13-15)    expectsReply: true,
[](#%5F%5Fcodelineno-13-16)  });
[](#%5F%5Fcodelineno-13-17)  return reply;
[](#%5F%5Fcodelineno-13-18)};
[](#%5F%5Fcodelineno-13-19)
[](#%5F%5Fcodelineno-13-20)const updateState = async () => {
[](#%5F%5Fcodelineno-13-21)  await Watch.updateState({ data: { counter: 42 } });
[](#%5F%5Fcodelineno-13-22)};
[](#%5F%5Fcodelineno-13-23)
[](#%5F%5Fcodelineno-13-24)const transferUserInfo = async () => {
[](#%5F%5Fcodelineno-13-25)  await Watch.transferUserInfo({ data: { sentAt: Date.now() } });
[](#%5F%5Fcodelineno-13-26)};
[](#%5F%5Fcodelineno-13-27)
[](#%5F%5Fcodelineno-13-28)const addListeners = async () => {
[](#%5F%5Fcodelineno-13-29)  await Watch.addListener('messageReceived', async event => {
[](#%5F%5Fcodelineno-13-30)    if (event.messageId) {
[](#%5F%5Fcodelineno-13-31)      await Watch.replyToMessage({
[](#%5F%5Fcodelineno-13-32)        data: { text: 'Hello back!' },
[](#%5F%5Fcodelineno-13-33)        messageId: event.messageId,
[](#%5F%5Fcodelineno-13-34)      });
[](#%5F%5Fcodelineno-13-35)    }
[](#%5F%5Fcodelineno-13-36)  });
[](#%5F%5Fcodelineno-13-37)  await Watch.addListener('reachabilityChange', event => {
[](#%5F%5Fcodelineno-13-38)    console.log('Reachable:', event.reachable);
[](#%5F%5Fcodelineno-13-39)  });
[](#%5F%5Fcodelineno-13-40)  await Watch.addListener('stateReceived', event => {
[](#%5F%5Fcodelineno-13-41)    console.log('State received:', event.data);
[](#%5F%5Fcodelineno-13-42)  });
[](#%5F%5Fcodelineno-13-43)  await Watch.addListener('userInfoReceived', event => {
[](#%5F%5Fcodelineno-13-44)    console.log('User info received:', event.data);
[](#%5F%5Fcodelineno-13-45)  });
[](#%5F%5Fcodelineno-13-46)};
`

## API[¶](#api "Permanent link")

* [getConnectionInfo()](#getconnectioninfo)
* [getReceivedState()](#getreceivedstate)
* [replyToMessage(...)](#replytomessage)
* [sendMessage(...)](#sendmessage)
* [transferUserInfo(...)](#transferuserinfo)
* [updateState(...)](#updatestate)
* [addListener('messageReceived', ...)](#addlistenermessagereceived-)
* [addListener('reachabilityChange', ...)](#addlistenerreachabilitychange-)
* [addListener('stateReceived', ...)](#addlistenerstatereceived-)
* [addListener('userInfoReceived', ...)](#addlisteneruserinforeceived-)
* [removeAllListeners()](#removealllisteners)
* [Interfaces](#interfaces)

### getConnectionInfo()[¶](#getconnectioninfo "Permanent link")

`[](#%5F%5Fcodelineno-14-1)getConnectionInfo() => Promise<GetConnectionInfoResult>
`

Get information about the connection to the watch.

Only available on Android and iOS.

**Returns:** `Promise<[GetConnectionInfoResult](#getconnectioninforesult)>`

**Since:** 0.0.1

---

### getReceivedState()[¶](#getreceivedstate "Permanent link")

`[](#%5F%5Fcodelineno-15-1)getReceivedState() => Promise<GetReceivedStateResult>
`

Get the last state that was received from the watch.

The state is persisted and can be read at any time, including after an app restart.

Only available on Android and iOS.

**Returns:** `Promise<[GetReceivedStateResult](#getreceivedstateresult)>`

**Since:** 0.0.1

---

### replyToMessage(...)[¶](#replytomessage "Permanent link")

`[](#%5F%5Fcodelineno-16-1)replyToMessage(options: ReplyToMessageOptions) => Promise<void>
`

Reply to a message that was received from the watch.

This is only possible if the `messageReceived` event provided a `messageId`.

Only available on Android and iOS.

| Param       | Type                                            |
| ----------- | ----------------------------------------------- |
| **options** | [ReplyToMessageOptions](#replytomessageoptions) |

**Since:** 0.0.1

---

### sendMessage(...)[¶](#sendmessage "Permanent link")

`[](#%5F%5Fcodelineno-17-1)sendMessage(options: SendMessageOptions) => Promise<SendMessageResult>
`

Send a message to the watch for immediate delivery.

The watch must be reachable, otherwise the call is rejected.

Only available on Android and iOS.

| Param       | Type                                      |
| ----------- | ----------------------------------------- |
| **options** | [SendMessageOptions](#sendmessageoptions) |

**Returns:** `Promise<[SendMessageResult](#sendmessageresult)>`

**Since:** 0.0.1

---

### transferUserInfo(...)[¶](#transferuserinfo "Permanent link")

`[](#%5F%5Fcodelineno-18-1)transferUserInfo(options: TransferUserInfoOptions) => Promise<void>
`

Transfer data to the watch in a queue.

In contrast to `updateState(...)`, every transfer is delivered, even if the watch is currently not reachable.

On iOS, the transfers are delivered in the order they were queued. On Android, there is no ordering guarantee between transfers.

Only available on Android and iOS.

| Param       | Type                                                |
| ----------- | --------------------------------------------------- |
| **options** | [TransferUserInfoOptions](#transferuserinfooptions) |

**Since:** 0.0.1

---

### updateState(...)[¶](#updatestate "Permanent link")

`[](#%5F%5Fcodelineno-19-1)updateState(options: UpdateStateOptions) => Promise<void>
`

Update the state that is delivered to the watch.

Only the latest state is delivered. If the watch is currently not reachable, the state is delivered as soon as it is reachable again.

Only available on Android and iOS.

| Param       | Type                                      |
| ----------- | ----------------------------------------- |
| **options** | [UpdateStateOptions](#updatestateoptions) |

**Since:** 0.0.1

---

### addListener('messageReceived', ...)[¶](#addlistenermessagereceived "Permanent link")

`[](#%5F%5Fcodelineno-20-1)addListener(eventName: 'messageReceived', listenerFunc: (event: MessageReceivedEvent) => void) => Promise<PluginListenerHandle>
`

Called when a message from the watch is received.

Only available on Android and iOS.

| Param            | Type                                                           |
| ---------------- | -------------------------------------------------------------- |
| **eventName**    | 'messageReceived'                                              |
| **listenerFunc** | (event: [MessageReceivedEvent](#messagereceivedevent)) => void |

**Returns:** `Promise<[PluginListenerHandle](#pluginlistenerhandle)>`

**Since:** 0.0.1

---

### addListener('reachabilityChange', ...)[¶](#addlistenerreachabilitychange "Permanent link")

`[](#%5F%5Fcodelineno-21-1)addListener(eventName: 'reachabilityChange', listenerFunc: (event: ReachabilityChangeEvent) => void) => Promise<PluginListenerHandle>
`

Called when the reachability of the watch changes.

Only available on Android and iOS.

| Param            | Type                                                                 |
| ---------------- | -------------------------------------------------------------------- |
| **eventName**    | 'reachabilityChange'                                                 |
| **listenerFunc** | (event: [ReachabilityChangeEvent](#reachabilitychangeevent)) => void |

**Returns:** `Promise<[PluginListenerHandle](#pluginlistenerhandle)>`

**Since:** 0.0.1

---

### addListener('stateReceived', ...)[¶](#addlistenerstatereceived "Permanent link")

`[](#%5F%5Fcodelineno-22-1)addListener(eventName: 'stateReceived', listenerFunc: (event: StateReceivedEvent) => void) => Promise<PluginListenerHandle>
`

Called when a state update from the watch is received.

Only available on Android and iOS.

| Param            | Type                                                       |
| ---------------- | ---------------------------------------------------------- |
| **eventName**    | 'stateReceived'                                            |
| **listenerFunc** | (event: [StateReceivedEvent](#statereceivedevent)) => void |

**Returns:** `Promise<[PluginListenerHandle](#pluginlistenerhandle)>`

**Since:** 0.0.1

---

### addListener('userInfoReceived', ...)[¶](#addlisteneruserinforeceived "Permanent link")

`[](#%5F%5Fcodelineno-23-1)addListener(eventName: 'userInfoReceived', listenerFunc: (event: UserInfoReceivedEvent) => void) => Promise<PluginListenerHandle>
`

Called when a user info transfer from the watch is received.

Only available on Android and iOS.

| Param            | Type                                                             |
| ---------------- | ---------------------------------------------------------------- |
| **eventName**    | 'userInfoReceived'                                               |
| **listenerFunc** | (event: [UserInfoReceivedEvent](#userinforeceivedevent)) => void |

**Returns:** `Promise<[PluginListenerHandle](#pluginlistenerhandle)>`

**Since:** 0.0.1

---

### removeAllListeners()[¶](#removealllisteners "Permanent link")

`[](#%5F%5Fcodelineno-24-1)removeAllListeners() => Promise<void>
`

Remove all listeners for this plugin.

**Since:** 0.0.1

---

### Interfaces[¶](#interfaces "Permanent link")

#### GetConnectionInfoResult[¶](#getconnectioninforesult "Permanent link")

| Prop                  | Type            | Description                                                                                                                                                                                                        | Since |
| --------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----- |
| **paired**            | boolean \| null | Whether or not a watch is paired with the device. On Android, this value is always null since the platform does not provide this information.                                                                      | 0.0.1 |
| **reachable**         | boolean         | Whether or not the watch is currently reachable for immediate message delivery. On Android, this requires that the watch app is installed and has declared the configured capability (default: capawesome\_watch). | 0.0.1 |
| **watchAppInstalled** | boolean \| null | Whether or not the watch app is installed on the watch. On Android, this is derived from the configured capability (default: capawesome\_watch) that the watch app must declare.                                   | 0.0.1 |

#### GetReceivedStateResult[¶](#getreceivedstateresult "Permanent link")

| Prop     | Type                            | Description                                                                                | Since |
| -------- | ------------------------------- | ------------------------------------------------------------------------------------------ | ----- |
| **data** | Record<string, unknown> \| null | The last state that was received from the watch or null if no state has been received yet. | 0.0.1 |

#### ReplyToMessageOptions[¶](#replytomessageoptions "Permanent link")

| Prop          | Type                    | Description                                                                          | Since |
| ------------- | ----------------------- | ------------------------------------------------------------------------------------ | ----- |
| **data**      | Record<string, unknown> | The data to send as reply. Must be JSON-serializable. null values are not supported. | 0.0.1 |
| **messageId** | string                  | The identifier of the message to reply to as provided by the messageReceived event.  | 0.0.1 |

#### SendMessageResult[¶](#sendmessageresult "Permanent link")

| Prop      | Type                            | Description                                                                  | Since |
| --------- | ------------------------------- | ---------------------------------------------------------------------------- | ----- |
| **reply** | Record<string, unknown> \| null | The reply that was received from the watch or null if no reply was expected. | 0.0.1 |

#### SendMessageOptions[¶](#sendmessageoptions "Permanent link")

| Prop             | Type                    | Description                                                                                                                | Default | Since |
| ---------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------- | ------- | ----- |
| **data**         | Record<string, unknown> | The data to send. Must be JSON-serializable. null values are not supported.                                                |         | 0.0.1 |
| **expectsReply** | boolean                 | Whether or not the watch is expected to reply to the message. If true, the call resolves as soon as the watch has replied. | false   | 0.0.1 |

#### TransferUserInfoOptions[¶](#transferuserinfooptions "Permanent link")

| Prop     | Type                    | Description                                                                     | Since |
| -------- | ----------------------- | ------------------------------------------------------------------------------- | ----- |
| **data** | Record<string, unknown> | The data to transfer. Must be JSON-serializable. null values are not supported. | 0.0.1 |

#### UpdateStateOptions[¶](#updatestateoptions "Permanent link")

| Prop     | Type                    | Description                                                                                        | Since |
| -------- | ----------------------- | -------------------------------------------------------------------------------------------------- | ----- |
| **data** | Record<string, unknown> | The data to deliver as the latest state. Must be JSON-serializable. null values are not supported. | 0.0.1 |

#### PluginListenerHandle[¶](#pluginlistenerhandle "Permanent link")

| Prop       | Type                |
| ---------- | ------------------- |
| **remove** | () => Promise<void> |

#### MessageReceivedEvent[¶](#messagereceivedevent "Permanent link")

| Prop          | Type                    | Description                                                                                                                      | Since |
| ------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **data**      | Record<string, unknown> | The data that was received.                                                                                                      | 0.0.1 |
| **messageId** | string \| null          | The identifier of the message if the watch expects a reply. In this case, you should reply using the replyToMessage(...) method. | 0.0.1 |

#### ReachabilityChangeEvent[¶](#reachabilitychangeevent "Permanent link")

| Prop          | Type    | Description                                                                     | Since |
| ------------- | ------- | ------------------------------------------------------------------------------- | ----- |
| **reachable** | boolean | Whether or not the watch is currently reachable for immediate message delivery. | 0.0.1 |

#### StateReceivedEvent[¶](#statereceivedevent "Permanent link")

| Prop     | Type                    | Description                 | Since |
| -------- | ----------------------- | --------------------------- | ----- |
| **data** | Record<string, unknown> | The data that was received. | 0.0.1 |

#### UserInfoReceivedEvent[¶](#userinforeceivedevent "Permanent link")

| Prop     | Type                    | Description                 | Since |
| -------- | ----------------------- | --------------------------- | ----- |
| **data** | Record<string, unknown> | The data that was received. | 0.0.1 |

## Communication Channels[¶](#communication-channels "Permanent link")

The plugin exposes the three communication channels of the platforms with honest, platform-true semantics:

| Method                | Semantics                         | iOS                      | Android                | Guarantee                                      |
| --------------------- | --------------------------------- | ------------------------ | ---------------------- | ---------------------------------------------- |
| sendMessage(...)      | Live, interactive, optional reply | WCSession.sendMessage    | MessageClient          | Requires reachability, not queued              |
| updateState(...)      | Latest state wins                 | updateApplicationContext | DataItem (fixed path)  | Replaces undelivered state, survives restarts  |
| transferUserInfo(...) | Queued, all delivered             | transferUserInfo         | DataItem (unique path) | Queued until delivered, even across relaunches |

The payload of all channels is limited to about 100 KB by the operating systems.

## Platform Behavior[¶](#platform-behavior "Permanent link")

The two platform stacks behave differently in some aspects. The plugin does not paper over these differences:

| Behavior                   | iOS                                                               | Android                                                                         |
| -------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| Watch → phone sendMessage  | Wakes the phone app in the background if it is not running.       | Starts the plugin's WearableListenerService; the event is queued for JS.        |
| Phone → watch sendMessage  | Does **not** launch the watch app. The watch app must be running. | Does **not** launch the watch app. The watch app's listener service is started. |
| paired / watchAppInstalled | Provided by the system.                                           | paired is always null; watchAppInstalled is derived from the capability.        |
| State persistence          | The latest received state is persisted by the system.             | The state is persisted and replicated by the Data Layer.                        |
| Identical state updates    | May not be redelivered if the data did not change.                | May not be redelivered if the data did not change.                              |
| Queued transfers           | Delivered in the order they were queued.                          | No ordering guarantee. The 100 most recent undelivered transfers are kept.      |
| Payload types              | Must be property list compatible; null values are not supported.  | Any JSON-serializable data.                                                     |

**Note**: A Wear OS watch that is paired to an iPhone is **not** supported. The Google Play services Data Layer only works between an Android phone and a Wear OS watch.

## FAQ[¶](#faq "Permanent link")

### How is this plugin different from other similar plugins?[¶](#how-is-this-plugin-different-from-other-similar-plugins "Permanent link")

It is a single, unified bridge between your Capacitor app and native Apple Watch and Wear OS apps, exposing the three platform channels honestly — live messages with optional replies, latest-wins state sync, and queued transfers for guaranteed delivery — plus reachability info and background reception of data that arrives while your app is closed. It even ships native watch-side SDKs for watchOS and Wear OS and needs no `AppDelegate` or `MainActivity` changes, so you build your watch UI natively and wire up communication with minimal boilerplate. Everything is fully typed, actively maintained against the latest OS and Capacitor versions and backed by dedicated support.

### Do I need to modify my AppDelegate on iOS?[¶](#do-i-need-to-modify-my-appdelegate-on-ios "Permanent link")

No. The plugin activates the `WCSession` when it is loaded and handles all session delegate callbacks internally, including background deliveries that launch the app.

### What happens to data that arrives while my app is closed?[¶](#what-happens-to-data-that-arrives-while-my-app-is-closed "Permanent link")

On Android, the plugin's manifest-registered `WearableListenerService` receives the data even while your app is not running and persists it, so the events are replayed as soon as your listeners are registered, even after an app restart. On iOS, a message from the watch wakes your app in the background and the events are retained in memory until your listeners are registered. Events that have not been consumed are therefore lost on iOS if the app is terminated in the meantime.

### Can my Wear OS watch app communicate with an iPhone app?[¶](#can-my-wear-os-watch-app-communicate-with-an-iphone-app "Permanent link")

No. The Google Play services Data Layer only works between an Android phone and a Wear OS watch. Likewise, an Apple Watch can only communicate with an iPhone. This is a platform limitation, not a plugin limitation.

### Why does `sendMessage(...)` reject with `WATCH_NOT_REACHABLE`?[¶](#why-does-sendmessage-reject-with-watch%5Fnot%5Freachable "Permanent link")

The message channel is a live channel and requires the watch to be reachable. On Android, also make sure that your watch app declares the `capawesome_watch` capability (see the Wear OS setup). If you need guaranteed delivery, use `transferUserInfo(...)` instead.

### Does the watch app UI come from the plugin?[¶](#does-the-watch-app-ui-come-from-the-plugin "Permanent link")

No, and that is deliberate. You build your watch UI natively (e.g. with SwiftUI or Jetpack Compose) with the full power of the platform, and use the shipped watch-side SDKs to communicate with your Capacitor app.

### Can I use this plugin with Ionic, React, Vue or Angular?[¶](#can-i-use-this-plugin-with-ionic-react-vue-or-angular "Permanent link")

Yes, the plugin is framework-agnostic. It works in any Capacitor app regardless of the web framework, including Ionic with Angular, React, or Vue, as well as plain JavaScript projects.

## Related Plugins[¶](#related-plugins "Permanent link")

* [Health](https://capawesome.io/docs/sdks/capacitor/health/): Read health and fitness data that pairs well with a watch experience.
* [Background Geolocation](https://capawesome.io/docs/sdks/capacitor/background-geolocation/): Track the device location in the background.
* [Geofences](https://capawesome.io/docs/sdks/capacitor/geofences/): Monitor geographic regions, even when the app is closed.

## Newsletter[¶](#newsletter "Permanent link")

Stay up to date with the latest news and updates about the Capawesome, Capacitor, and Ionic ecosystem by subscribing to our [Capawesome Newsletter](https://cloud.capawesome.io/newsletter/).

## Changelog[¶](#changelog "Permanent link")

See [CHANGELOG.md](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/watch/CHANGELOG.md).

## Breaking Changes[¶](#breaking-changes "Permanent link")

See [BREAKING.md](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/watch/BREAKING.md).

## License[¶](#license "Permanent link")

See [LICENSE](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/watch/LICENSE).

August 15, 2026 

Back to top

```json
{"@context": "https://schema.org", "@graph": [{"@type": "TechArticle", "@id": "https://capawesome.io/docs/sdks/capacitor/watch/#article", "headline": "Capacitor Watch Plugin for Android & iOS", "name": "Capacitor Watch Plugin for Android & iOS", "description": "Capacitor Watch plugin to exchange messages, user info, and state between your app and Apple Watch and Wear OS companion apps.", "inLanguage": "en", "url": "https://capawesome.io/docs/sdks/capacitor/watch/", "mainEntityOfPage": "https://capawesome.io/docs/sdks/capacitor/watch/", "author": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}, "publisher": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}, "about": {"@id": "https://capawesome.io/docs/sdks/capacitor/watch/#software"}}, {"@type": "SoftwareSourceCode", "@id": "https://capawesome.io/docs/sdks/capacitor/watch/#software", "name": "Capacitor Watch Plugin for Android & iOS", "description": "Capacitor Watch plugin to exchange messages, user info, and state between your app and Apple Watch and Wear OS companion apps.", "url": "https://capawesome.io/docs/sdks/capacitor/watch/", "programmingLanguage": "TypeScript", "runtimePlatform": "Capacitor", "codeRepository": "https://github.com/capawesome-team", "author": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}, "publisher": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}}]}
{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "How is this plugin different from other similar plugins?", "acceptedAnswer": {"@type": "Answer", "text": "It is a single, unified bridge between your Capacitor app and native Apple Watch and Wear OS apps, exposing the three platform channels honestly — live messages with optional replies, latest-wins state sync, and queued transfers for guaranteed delivery — plus reachability info and background reception of data that arrives while your app is closed. It even ships native watch-side SDKs for watchOS and Wear OS and needs no AppDelegate or MainActivity changes, so you build your watch UI natively and wire up communication with minimal boilerplate. Everything is fully typed, actively maintained against the latest OS and Capacitor versions and backed by dedicated support."}}, {"@type": "Question", "name": "Do I need to modify my AppDelegate on iOS?", "acceptedAnswer": {"@type": "Answer", "text": "No. The plugin activates the WCSession when it is loaded and handles all session delegate callbacks internally, including background deliveries that launch the app."}}, {"@type": "Question", "name": "What happens to data that arrives while my app is closed?", "acceptedAnswer": {"@type": "Answer", "text": "On Android, the plugin's manifest-registered WearableListenerService receives the data even while your app is not running and persists it, so the events are replayed as soon as your listeners are registered, even after an app restart. On iOS, a message from the watch wakes your app in the background and the events are retained in memory until your listeners are registered. Events that have not been consumed are therefore lost on iOS if the app is terminated in the meantime."}}, {"@type": "Question", "name": "Can my Wear OS watch app communicate with an iPhone app?", "acceptedAnswer": {"@type": "Answer", "text": "No. The Google Play services Data Layer only works between an Android phone and a Wear OS watch. Likewise, an Apple Watch can only communicate with an iPhone. This is a platform limitation, not a plugin limitation."}}, {"@type": "Question", "name": "Why does sendMessage(...) reject with WATCH_NOT_REACHABLE?", "acceptedAnswer": {"@type": "Answer", "text": "The message channel is a live channel and requires the watch to be reachable. On Android, also make sure that your watch app declares the capawesome_watch capability (see the Wear OS setup). If you need guaranteed delivery, use transferUserInfo(...) instead."}}, {"@type": "Question", "name": "Does the watch app UI come from the plugin?", "acceptedAnswer": {"@type": "Answer", "text": "No, and that is deliberate. You build your watch UI natively (e.g. with SwiftUI or Jetpack Compose) with the full power of the platform, and use the shipped watch-side SDKs to communicate with your Capacitor app."}}, {"@type": "Question", "name": "Can I use this plugin with Ionic, React, Vue or Angular?", "acceptedAnswer": {"@type": "Answer", "text": "Yes, the plugin is framework-agnostic. It works in any Capacitor app regardless of the web framework, including Ionic with Angular, React, or Vue, as well as plain JavaScript projects."}}], "url": "https://capawesome.io/docs/sdks/capacitor/watch/"}
```
