A React Native module that enables smooth and reliable communication between an iOS app and its paired Apple Watch using Appleβs WatchConnectivity framework. This library offers an easy-to-use interface for sending messages, transferring files, syncing data, and monitoring the connection status between the iPhone and Apple Watch β all from a React Native app.
β οΈ Note: This module does NOT provide a way to build Apple Watch apps. A separate Watch app must still be developed using Swift or SwiftUI. This package is intended as a modern, actively maintained alternative to the previously available (but now outdated) React Native watch connectivity module.
π Contributions are welcome! If you'd like to improve the module or add new features, feel free to open an issue or submit a pull request.
npm install rn-watch-connect
# or
yarn add rn-watch-connect
- πΆ Monitor watch connectivity status
- π¬ Send messages between iPhone and Apple Watch
- π Transfer files between iPhone and Apple Watch
- π Sync data between iPhone and Apple Watch
- π‘ Event-based communication
- π§ TypeScript support with generic types
- π© Promise-based message sending with reply support
Property | Type | Description |
---|---|---|
isWatchSupported |
boolean |
Indicates if the device supports Watch Connectivity |
isWatchPaired |
boolean |
Indicates if an Apple Watch is paired with the device |
isWatchAppInstalled |
boolean |
Indicates if the Watch app is installed |
isWatchReachable |
boolean |
Indicates if the paired Watch is currently reachable |
watchActivationState |
string |
Current activation state of the Watch Connectivity session |
applicationContext |
{ [key: string]: any } |
Current application context |
receivedApplicationContext |
{ [key: string]: any } |
Received application context from the Watch |
outstandingUserInfoTransfers |
OutstandingUserInfoTransfer[] |
Outstanding user info transfers |
outstandingFileTransfers |
FileTransfer[] |
Outstanding file transfers |
Sends a message to the paired Apple Watch and waits for a reply.
Type Parameters:
T
: Type of the message to send (defaults toRecord<string, any>
)R
: Type of the expected reply (defaults toRecord<string, any>
)
Parameters:
message
: The message to send to the Watch
Returns:
Promise<R>
: A promise that resolves with the Watch's reply
Note: The following delegate method is expected to receive the message on the receiver app
- On Counter app (receiver):
func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void)
Example:
type MyMessage = {
message: string;
};
type MyReply = {
response: string;
};
const reply = await RnWatchConnect.sendMessage<MyMessage, MyReply>({
message: "Hello from iPhone!",
});
Sends a message to the paired Apple Watch without expecting a reply.
Type Parameters:
T
: Type of the message to send (defaults toRecord<string, any>
)
Parameters:
message
: The message to send to the Watch
Note: The following delegate method is expected to receive the message on the receiver app
- On Watch app (receiver):
func session(_ session: WCSession, didReceiveMessage message: [String : Any])
Example:
await RnWatchConnect.sendMessageWithoutReply({
message: "Hello from iPhone!",
});
Sends a reply to a message received from the Watch.
Parameters:
replyId
: The ID of the message to reply toreply
: The reply message to send
Example:
RnWatchConnect.replyToMessage(replyId, {
response: "Hello from iPhone!",
});
Sends a base64 encoded data message to the paired Apple Watch and waits for a reply.
Parameters:
data
: A base64 encoded string to send to the Watch
Returns:
Promise<string>
: A promise that resolves with the Watch's base64 encoded reply
Note: The following delegate method is expected to receive the message on the receiver app
- On Watch app (receiver):
func session(_ session: WCSession, didReceiveMessageData messageData: Data, replyHandler: @escaping (Data) -> Void)
Example:
try {
const reply = await RnWatchConnect.sendDataMessage(
"SGVsbG8gZnJvbSBpUGhvbmUh"
); // "Hello from iPhone!" in base64
console.log("Decoded reply:", Buffer.from(reply, "base64").toString());
} catch (error) {
console.log("Error:", error);
}
Sends a base64 encoded data message to the paired Apple Watch without expecting a reply.
Parameters:
data
: A base64 encoded string to send to the Watch
Note: The following delegate method is expected to receive the message on the receiver app
- On Watch app (receiver):
func session(_ session: WCSession, didReceiveMessageData messageData: Data)
Example:
try {
await RnWatchConnect.sendDataMessageWithoutReply("SGVsbG8gZnJvbSBpUGhvbmUh");
} catch (error) {
console.log("Error:", error);
}
Sends a reply to a data message received from the Watch.
Parameters:
replyId
: The ID of the message to reply toresponse
: The base64 encoded response string
Example:
RnWatchConnect.replyToDataMessage(
event.replyId,
"TWVzc2FnZSByZWNlaXZlZCBvbiBSZWFjdCBOYXRpdmUh"
);
Updates the application context on the Watch.
Parameters:
applicationContext
: The application context to update (defaults toRecord<string, any>
)
Example:
await RnWatchConnect.updateApplicationContext({
theme: "red",
});
Transfers user info to the Watch.
Parameters:
userInfo
: The user info to transfer (defaults toRecord<string, any>
)
Returns:
UserInfoTransfer
: The transfer ID and isTransferring status
Example:
const transfer = RnWatchConnect.transferUserInfo({
message: "Hello from iPhone!",
});
Cancels a pending user info transfer.
Parameters:
transferId
: The ID of the transfer to cancel
Returns:
{ id: string }
: The transfer ID
Example:
RnWatchConnect.cancelUserInfoTransfer(transfer.id);
Transfers a file to the Watch.
Parameters:
file
: The file URL to transfermetadata
: The metadata to transfer (defaults toRecord<string, any>
) (optional)
Returns:
FileTransfer
: Object containing the transfer information
Example:
const transfer = RnWatchConnect.transferFile("file://path/to/file.txt", {
name: "file.txt",
});
Cancels a pending file transfer.
Parameters:
transferId
: The ID of the transfer to cancel
Returns:
{ id: string }
: The transfer ID
Example:
RnWatchConnect.cancelFileTransfer(transfer.id);
Triggered when a message is received from the Watch. It doesn't require a response. The event object is the message object received from the Watch.
Example:
useEventListener(RnWatchConnect, "onMessageReceived", (event) => {
console.log("Message received:", event);
});
Triggered when a message requiring a reply is received from the Watch. The event object is an object with the following properties:
message
: The message object received from the WatchreplyId
: The ID of the message to reply to
Example:
useEventListener(RnWatchConnect, "onMessageWithReply", (event) => {
console.log("Message received:", event.message);
RnWatchConnect.replyToMessage(event.replyId, {
response: "Reply from iPhone",
});
});
Triggered when a data message is received from the Watch. The event object is an object with the following properties:
data
: The base64 encoded data received from the Watch
Example:
useEventListener(RnWatchConnect, "onDataMessageReceived", (event) => {
console.log("Data message received:", event.data);
});
Triggered when a data message requiring a reply is received from the Watch. The event object is an object with the following properties:
data
: The base64 encoded data received from the WatchreplyId
: The ID of the message to reply to
Example:
useEventListener(RnWatchConnect, "onDataMessageWithReply", (event) => {
console.log("Data message received:", event.data);
RnWatchConnect.replyToDataMessage(event.replyId, "SGVsbG8gZnJvbSBpUGhvbmUh");
});
Triggered when user info is received from the Watch. The event object is the user info object received from the Watch.
Example:
useEventListener(RnWatchConnect, "onUserInfoReceived", (event) => {
console.log("User info received:", event);
});
Triggered when a file is received from the Watch. The event object is an object with the following properties:
File
: The file object received from the Watch
Example:
useEventListener(RnWatchConnect, "onFileReceived", (event) => {
console.log("File received:", event);
});
Triggered when the Watch's reachability status changes.
Example:
useEventListener(
RnWatchConnect,
"onReachabilityChanged",
({ isWatchReachable }) => {
console.log("Watch reachability changed:", isWatchReachable);
}
);
Triggered when the Watch pairing status changes.
Example:
useEventListener(
RnWatchConnect,
"onWatchPairedChanged",
({ isWatchPaired }) => {
console.log("Watch paired status changed:", isWatchPaired);
}
);
Triggered when the Watch app installation status changes.
Example:
useEventListener(
RnWatchConnect,
"onWatchAppInstallChanged",
({ isWatchAppInstalled }) => {
console.log("Watch app installation status changed:", isWatchAppInstalled);
}
);
Triggered when the application context changes.
Example:
useEventListener(
RnWatchConnect,
"onApplicationContextChanged",
(applicationContext) =>
console.log("Application context changed:", applicationContext)
);
Property | Type | Description |
---|---|---|
id | string | Unique identifier for the transfer |
userInfo | Record<string, any> | The user info payload being transferred |
isTransferring | boolean | Whether the transfer is currently in progress |
Property | Type | Description |
---|---|---|
id | string | Unique identifier for the transfer |
isTransferring | boolean | Whether the transfer is currently in progress |
Property | Type | Description |
---|---|---|
id | string | Unique identifier for the transfer |
isTransferring | boolean | Whether the transfer is currently in progress |
progress | FileProgress | The progress of the file transfer |
file | File | The file being transferred |
Property | Type | Description |
---|---|---|
fileURL | string | The URL of the file being transferred |
metadata | Record<string, any> | The metadata associated with the file |
Property | Type | Description |
---|---|---|
fractionCompleted | number | The fraction of the file transfer that has been completed |
completedUnitCount | number | The number of bytes transferred so far |
totalUnitCount | number | The total number of bytes to be transferred |
The module is fully typed and supports generic types for messages and replies. You can define your own types for messages and replies:
// Define your message types
type MyMessage = {
message: string;
// ... other properties
};
type MyReply = {
response: string;
// ... other properties
};
// Use them in your code
const reply = await RnWatchConnect.sendMessage<MyMessage, MyReply>({
message: "Hello",
});
MIT