Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,15 @@ The example of implementation available in the [CounterScreen](example/src/Count
https://mtford.co.uk/projects/react-native-watch-connectivity/docs/communication/

```js
import { sendMessage } from 'react-native-wear-connectivity';
import { sendMessage, sendMessageAsync } from 'react-native-wear-connectivity';

// Callback API
sendMessage({ text: 'Hello watch!' }, (reply) => {
console.log(reply); // {"text": "Hello React Native app!"}
});

// Promise API
await sendMessageAsync({ text: 'Hello watch!' });
```

### Receive Messages
Expand Down Expand Up @@ -291,13 +295,20 @@ useEffect(() => {

**Sending messages from React Native Mobile Device to Jetpack Compose WearOS**

The React Native Mobile App Example sends messages to the WearOS Jetpack Compose example with [sendMessage](https://github.com/fabOnReact/react-native-wear-connectivity/blob/2f936622422e197c22bef228b44eb24b46c878ae/example/src/CounterScreen/index.android.tsx#L29-L33).
The React Native Mobile App Example sends messages to the WearOS Jetpack Compose example with `sendMessageAsync` (a Promise based API). The callback based `sendMessage` is still available for backward compatibility.

```javascript
const sendMessageToWear = () => {
import { sendMessageAsync } from 'react-native-wear-connectivity';

const sendMessageToWear = async () => {
setDisabled(true);
const json = { text: 'hello' };
sendMessage(json, onSuccess, onError);
try {
await sendMessageAsync(json);
onSuccess('message sent');
} catch (error) {
onError(error);
}
};
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,38 @@ public void sendMessage(ReadableMap messageData, Callback replyCb, Callback erro
}
}

/**
* Sends a message and resolves or rejects a promise.
*/
@ReactMethod
public void sendMessageAsync(ReadableMap messageData, Promise promise) {
Callback errorCb = new Callback() {
@Override
public void invoke(Object... args) {
String message = (args != null && args.length > 0) ? args[0].toString() : "";
promise.reject("E_SEND_MESSAGE_FAILED", message);
}
};

List<Node> connectedNodes = retrieveNodes(errorCb);
if (connectedNodes == null) {
return;
}

if (!connectedNodes.isEmpty()) {
Callback replyCb = new Callback() {
@Override
public void invoke(Object... args) {
Object reply = (args != null && args.length > 0) ? args[0] : null;
promise.resolve(reply);
}
};
messageClient.sendMessage(messageData, connectedNodes, replyCb, errorCb);
} else {
promise.reject("E_NO_NODES", NO_NODES_FOUND);
}
}

private List<Node> retrieveNodes(Callback errorCb) {
try {
int result = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(getReactContext());
Expand Down
3 changes: 3 additions & 0 deletions android/src/oldarch/WearConnectivitySpec.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.Promise;

abstract class WearConnectivitySpec extends ReactContextBaseJavaModule {
WearConnectivitySpec(ReactApplicationContext context) {
super(context);
}

public abstract void sendMessage(ReadableMap messageData, Callback replyCb, Callback errCb);

public abstract void sendMessageAsync(ReadableMap messageData, Promise promise);
}
19 changes: 17 additions & 2 deletions docs/alternative-installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ Example implementation of the above counter application for WearOS and Android M
```js
import React, { useEffect, useState } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import { sendMessage, watchEvents } from 'react-native-wear-connectivity';
import { sendMessage, sendMessageAsync, watchEvents } from 'react-native-wear-connectivity';

function App() {
return <CounterScreen />;
Expand All @@ -130,9 +130,20 @@ function CounterScreen() {
sendMessage(json, onSuccess, onError);
};

const sendMessageToWearAsync = async () => {
const json = { text: 'hello' };
try {
const result = await sendMessageAsync(json);
console.log(result);
} catch (error) {
console.log(error);
}
};

return (
<View style={styles.container}>
<Button title="increase counter" onPress={sendMessageToWear} />
<Button title="increase counter async" onPress={sendMessageToWearAsync} />
<Text style={styles.count}>The count is {count}</Text>
</View>
);
Expand Down Expand Up @@ -166,9 +177,13 @@ export default App;
### Send Messages

```js
import { sendMessage } from 'react-native-wear-connectivity';
import { sendMessage, sendMessageAsync } from 'react-native-wear-connectivity';

// Callback based API
sendMessage({ text: 'Hello watch!' });

// Promise based API
await sendMessageAsync({ text: 'Hello watch!' });
```

### Receive Messages
Expand Down
11 changes: 8 additions & 3 deletions example/src/CounterScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { View, StyleSheet, Text, Button } from 'react-native';
import { launchImageLibrary } from 'react-native-image-picker';
import {
startFileTransfer,
sendMessage,
sendMessageAsync,
watchEvents,
} from 'react-native-wear-connectivity';
import type {
Expand Down Expand Up @@ -32,10 +32,15 @@ function CounterScreen() {
};
const onError: ErrorCallback = (error) => console.log(error);

const sendMessageToWear = () => {
const sendMessageToWear = async () => {
setDisabled(true);
const json = { text: 'hello' };
sendMessage(json, onSuccess, onError);
try {
const result = await sendMessageAsync(json);
onSuccess(result);
} catch (error) {
onError(String(error));
}
};

const sendFileToWear = async () => {
Expand Down
3 changes: 3 additions & 0 deletions src/NativeWearConnectivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ export type SendMessage = (
errCb: ErrorCallback
) => void;

export type SendMessageAsync = (message: Payload) => Promise<any>;

export type SendFile = (file: string, metadata: unknown) => Promise<any>;

export interface Spec extends TurboModule {
sendMessage: SendMessage;
sendMessageAsync: SendMessageAsync;
sendFile: SendFile;
}

Expand Down
10 changes: 8 additions & 2 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AppRegistry } from 'react-native';
import { NativeModules, Platform } from 'react-native';
import { watchEvents } from './subscriptions';
import { sendMessage } from './messages';
import { sendMessage, sendMessageAsync } from './messages';
import type {
ReplyCallback,
ErrorCallback,
Expand Down Expand Up @@ -37,7 +37,13 @@ const startFileTransfer: SendFile = (file, _metadata) => {
return WearConnectivity.sendFile(file, _metadata);
};

export { startFileTransfer, sendMessage, watchEvents, WearConnectivity };
export {
startFileTransfer,
sendMessage,
sendMessageAsync,
watchEvents,
WearConnectivity,
};
export type { ReplyCallback, ErrorCallback };

type WearParameters = {
Expand Down
20 changes: 18 additions & 2 deletions src/messages.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { Platform } from 'react-native';
import type { SendMessage, Payload } from './NativeWearConnectivity';
import type {
SendMessage,
SendMessageAsync,
Payload,
} from './NativeWearConnectivity';
import { WearConnectivity } from './index';
import { LIBRARY_NAME, IOS_NOT_SUPPORTED_WARNING } from './constants';

Expand Down Expand Up @@ -28,12 +32,24 @@ const sendMessage: SendMessage = (message, cb, errCb) => {
);
};

const sendMessageAsync: SendMessageAsync = (message) => {
const json: Payload = { ...message, event: 'message' };
return WearConnectivity.sendMessageAsync(json);
};

const sendMessageMock: SendMessage = () =>
console.warn(LIBRARY_NAME + 'message' + IOS_NOT_SUPPORTED_WARNING);

const sendMessageAsyncMock: SendMessageAsync = () => {
console.warn(LIBRARY_NAME + 'message' + IOS_NOT_SUPPORTED_WARNING);
return Promise.reject(LIBRARY_NAME + 'message' + IOS_NOT_SUPPORTED_WARNING);
};

let sendMessageExport: SendMessage = sendMessageMock;
let sendMessageAsyncExport: SendMessageAsync = sendMessageAsyncMock;
if (Platform.OS !== 'ios') {
sendMessageExport = sendMessage;
sendMessageAsyncExport = sendMessageAsync;
}

export { sendMessageExport as sendMessage };
export { sendMessageExport as sendMessage, sendMessageAsyncExport as sendMessageAsync };