Getting Started
-
Install the package
Terminal window npm i @capgo/capacitor-watchTerminal window pnpm add @capgo/capacitor-watchTerminal window yarn add @capgo/capacitor-watchTerminal window bun add @capgo/capacitor-watch -
Sync with native projects
Terminal window npx cap syncTerminal window pnpm cap syncTerminal window yarn cap syncTerminal window bunx cap sync -
Configure the plugin
Basic Usage Example:
import { CapgoWatch } from '@capgo/capacitor-watch';// Check watch connectivity statusconst info = await CapgoWatch.getInfo();console.log('Watch paired:', info.isPaired);console.log('Watch reachable:', info.isReachable);// Listen for messages from watchawait CapgoWatch.addListener('messageReceived', (event) => {console.log('Message from watch:', event.message);});Send a Message to Watch:
// Check if watch is reachable firstconst info = await CapgoWatch.getInfo();if (info.isReachable) {await CapgoWatch.sendMessage({data: { action: 'refresh', timestamp: Date.now() }});}Required iOS Setup:
- Add the WatchConnectivity capability to your iOS app in Xcode
- Create a watchOS app target in your Xcode project
- Implement WatchConnectivity in your watchOS app (see Watch App Implementation below)
The plugin automatically activates the WCSession when the plugin loads.
Apple Watch is only supported on iOS. On Android, all methods will reject with “Apple Watch is only supported on iOS” error. The
getInfo()method returnsisSupported: false. -
Handle messages that require a reply
// Listen for messages that need a responseawait CapgoWatch.addListener('messageReceivedWithReply', async (event) => {console.log('Request from watch:', event.message);// Process the requestconst result = await processWatchRequest(event.message);// Send reply back to watchawait CapgoWatch.replyToMessage({callbackId: event.callbackId,data: { result }});}); -
Sync application state
// Update application context (latest value only)await CapgoWatch.updateApplicationContext({context: {theme: 'dark',userId: '123',lastSync: Date.now()}});// Listen for context updates from watchawait CapgoWatch.addListener('applicationContextReceived', (event) => {console.log('Context from watch:', event.context);}); -
Transfer user info reliably
// Queue data for reliable delivery (even when watch is offline)await CapgoWatch.transferUserInfo({userInfo: {recordId: '456',action: 'created',data: { name: 'Item 1' }}});// Listen for user info transfersawait CapgoWatch.addListener('userInfoReceived', (event) => {console.log('User info from watch:', event.userInfo);}); -
Monitor connectivity
// Track reachability changesawait CapgoWatch.addListener('reachabilityChanged', (event) => {console.log('Watch reachable:', event.isReachable);if (event.isReachable) {// Watch is now available for interactive messaging}});// Track session activation stateawait CapgoWatch.addListener('activationStateChanged', (event) => {// 0 = notActivated, 1 = inactive, 2 = activatedconsole.log('Session state:', event.state);});
Watch App Implementation
Section titled “Watch App Implementation”Your watchOS app needs to implement WatchConnectivity. Here’s a SwiftUI example:
import SwiftUIimport WatchConnectivity
@mainstruct MyWatchApp: App { init() { WatchViewModel.shared.activate() }
var body: some Scene { WindowGroup { ContentView() } }}
class WatchViewModel: NSObject, ObservableObject, WCSessionDelegate { static let shared = WatchViewModel()
@Published var lastMessage: [String: Any] = [:]
func activate() { guard WCSession.isSupported() else { return } WCSession.default.delegate = self WCSession.default.activate() }
// Send message to iPhone func sendToPhone(_ data: [String: Any]) { guard WCSession.default.isReachable else { print("iPhone not reachable") return } WCSession.default.sendMessage(data, replyHandler: nil) }
// Send message with reply func sendToPhoneWithReply(_ data: [String: Any], completion: @escaping ([String: Any]) -> Void) { guard WCSession.default.isReachable else { return } WCSession.default.sendMessage(data, replyHandler: completion) }
// Receive message from iPhone func session(_ session: WCSession, didReceiveMessage message: [String: Any]) { DispatchQueue.main.async { self.lastMessage = message } }
// Receive application context func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String: Any]) { DispatchQueue.main.async { self.lastMessage = applicationContext } }
// Required delegate methods func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { print("Watch session activated: \(activationState.rawValue)") }}API Reference
Section titled “API Reference”Methods
Section titled “Methods”sendMessage(options: SendMessageOptions)
Section titled “sendMessage(options: SendMessageOptions)”Send an interactive message to the watch. Requires watch to be reachable.
Parameters:
data: Object - The data to send to the watch
updateApplicationContext(options: UpdateContextOptions)
Section titled “updateApplicationContext(options: UpdateContextOptions)”Update application context. Only latest value is kept.
Parameters:
context: Object - The context data to sync
transferUserInfo(options: TransferUserInfoOptions)
Section titled “transferUserInfo(options: TransferUserInfoOptions)”Queue user info for reliable delivery.
Parameters:
userInfo: Object - The user info to transfer
replyToMessage(options: ReplyMessageOptions)
Section titled “replyToMessage(options: ReplyMessageOptions)”Reply to a message that requested a response.
Parameters:
callbackId: string - The callback ID from messageReceivedWithReply eventdata: Object - The reply data
getInfo()
Section titled “getInfo()”Get watch connectivity status.
Returns: WatchInfo object with:
isSupported: boolean - Whether WatchConnectivity is availableisPaired: boolean - Whether a watch is pairedisWatchAppInstalled: boolean - Whether watch app is installedisReachable: boolean - Whether watch is reachableactivationState: number - Session state (0/1/2)
getPluginVersion()
Section titled “getPluginVersion()”Get the native plugin version.
Events
Section titled “Events”| Event | Description |
|---|---|
messageReceived | Simple message from watch |
messageReceivedWithReply | Message expecting a reply (includes callbackId) |
applicationContextReceived | Context update from watch |
userInfoReceived | User info transfer from watch |
reachabilityChanged | Watch connectivity changed |
activationStateChanged | Session activation state changed |
Communication Patterns
Section titled “Communication Patterns”Immediate Messaging (sendMessage)
Section titled “Immediate Messaging (sendMessage)”- Requires watch to be reachable
- Best for interactive, time-sensitive communication
- Fails immediately if watch is not available
Application Context (updateApplicationContext)
Section titled “Application Context (updateApplicationContext)”- Latest value only - previous values are overwritten
- Best for syncing current app state
- Delivered when watch becomes available
User Info Transfer (transferUserInfo)
Section titled “User Info Transfer (transferUserInfo)”- Queued and delivered in order
- Best for important data that must be delivered
- Works even when watch is temporarily unreachable
Platform Notes
Section titled “Platform Notes”- Requires iOS 15.0 or later
- Uses WatchConnectivity framework
- Session automatically activates on plugin load
- Supports background delivery for context and user info
Android
Section titled “Android”- Not supported (Apple Watch is iOS-only)
- All methods reject with appropriate error
getInfo()returnsisSupported: false
- Not supported
- All methods reject with unavailable error
getInfo()returnsisSupported: false
Common Use Cases
Section titled “Common Use Cases”- Data Sync: Keep watch and phone data in sync
- Remote Control: Control phone features from watch
- Notifications: Send custom notifications to watch
- Health Data: Share fitness and health metrics
- Media Control: Control music playback from watch
- Smart Home: Control devices from your wrist
Troubleshooting
Section titled “Troubleshooting”Watch not reachable:
- Ensure watch is within Bluetooth range
- Check that both apps are running
- Verify WCSession is activated on both sides
Messages not received:
- Check that listeners are registered before sending
- Verify the watch app implements WCSessionDelegate
- Use
transferUserInfofor guaranteed delivery
Session not activating:
- Ensure WatchConnectivity capability is added in Xcode
- Check that watch app has the companion bundle ID
- Verify both apps target compatible OS versions