Skip to content

Commit

Permalink
Chore/add tutorials (#1221)
Browse files Browse the repository at this point in the history
* chore: add tutorials
  • Loading branch information
intent-kacper-cyranowski authored Jul 17, 2024
1 parent c237a8d commit da2e860
Show file tree
Hide file tree
Showing 5 changed files with 290 additions and 46 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ It does NOT support:
- bluetooth classic devices.
- communicating between phones using BLE (Peripheral support)
- [bonding peripherals](https://github.com/dotintent/react-native-ble-plx/wiki/Device-Bonding)
- [beacons](https://github.com/dotintent/react-native-ble-plx/wiki/=-FAQ:-Beacons)

## Table of Contents

Expand All @@ -43,7 +44,7 @@ For old RN versions (<0.60) please check [old README](./docs/README_V1.md) (1.x)
for the old instructions or [migration guide](./docs/MIGRATION_V1.md).

| React Native | 3.1.2 |
|--------------| ------------------ |
| ------------ | ------------------ |
| 0.74.1 | :white_check_mark: |
| 0.69.6 | :white_check_mark: |
| Expo 51 | :white_check_mark: |
Expand Down
61 changes: 41 additions & 20 deletions INTRO.md → docs/GETTING_STARTED.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,52 @@
<h1 align="center">
<a href="https://github.com/dotintent/react-native-ble-plx"><img alt="react-native-ble-plx" src="logo.png" /></a>
<h1 align="center" >
<a href="https://github.com/dotintent/react-native-ble-plx"><img style="max-height: 300px;" alt="react-native-ble-plx" src="logo.png" /></a>
</h1>

This guide is an introduction to BLE stack and APIs exported by this library. All examples
will be based on CC2541 SensorTag.

## Creating BLE Manager
### Install and prepare package

First step is to create BleManager instance which is an entry point to all available APIs.
Make sure to create it after application started its execution. For example we can keep it
as a static reference:
In the case of Expo, you will need to prepare a plugin config, detailed information can be found here: https://github.com/dotintent/react-native-ble-plx?tab=readme-ov-file#expo-sdk-43
In the case of react native CLI you need to configure two environments:

```js
- [iOS](https://github.com/dotintent/react-native-ble-plx?tab=readme-ov-file#ios-example-setup)
- [Android](https://github.com/dotintent/react-native-ble-plx?tab=readme-ov-file#android-example-setup)

### Creating BLE Manager

First step is to create BleManager instance which is an entry point to all available APIs. It should be declared **OUTSIDE the life cycle of React**. Make sure to create it after application started its execution. We can keep it as a static reference by either creating our own abstraction (ex.1) or by simply creating a new instance (ex.2).

#### Ex.1

```ts
import { BleManager } from 'react-native-ble-plx'

// create your own singleton class
class BLEServiceInstance {
manager: BleManage

constructor() {
this.manager = new BleManager()
}
}

export const BLEService = new BLEServiceInstance()
```

#### Ex.2

```ts
import { BleManager } from 'react-native-ble-plx'

export const manager = new BleManager()
```

Only _one_ instance of BleManager is allowed. When you don't need any BLE functionality you
can destroy created instance by calling `manager.destroy()` function. You can then recreate
`BleManager` later on.
Only _one_ instance of BleManager is allowed. When you don't need any BLE functionality you can destroy created instance by calling `manager.destroy()` function. You can then recreate `BleManager` later on.

Note that you may experience undefined behaviour when calling a function on one `BleManager`
and continuing with another instance. A frequently made error is to create a new instance
of the manager for every re-render of a React Native Component.
Note that you may experience undefined behavior when calling a function on one `BleManager` and continuing with another instance. A frequently made error is to create a new instance of the manager for every re-render of a React Native Component.

## Ask for permissions
### Ask for permissions

Check if you requested following permissions

Expand Down Expand Up @@ -82,7 +103,7 @@ return (
)
```

## Waiting for Powered On state
### Waiting for Powered On state

When iOS application launches BLE stack is not immediately available and we need to check its status.
To detect current state and following state changes we can use `onStateChange()` function:
Expand All @@ -99,7 +120,7 @@ React.useEffect(() => {
}, [manager])
```

## Scanning devices
### Scanning devices

Devices needs to be scanned first to be able to connect to them. There is a simple function
which allows only one callback to be registered to handle detected devices:
Expand Down Expand Up @@ -128,11 +149,11 @@ It is worth to note that scanning function may emit one device multiple times. H
when device is connected it won't broadcast and needs to be disconnected from central
to be scanned again. Only one scanning listener can be registered.

### Bluetooth 5 Advertisements in Android
#### Bluetooth 5 Advertisements in Android

To see devices that use Bluetooth 5 Advertising Extension you have to set the `legacyScan` variable to `false` in {@link #scanoptions|Scan options} when you are starting {@link #blemanagerstartdevicescan|BleManager.startDeviceScan()},

## Connecting and discovering services and characteristics
### Connecting and discovering services and characteristics

Once device is scanned it is in disconnected state. We need to connect to it and discover
all services and characteristics it contains. Services may be understood
Expand Down Expand Up @@ -160,12 +181,12 @@ It can be a long process depending on number of characteristics and services ava
\* Extremely rarely, when peripheral's service/characteristic set can change during a connection
an additional service discovery may be needed.

## Read, write and monitor values
### Read, write and monitor values

After successful discovery of services you can call

- {@link #blemanagerreadcharacteristicfordevice|BleManager.readCharacteristicForDevice()},
- {@link #blemanagerwritecharacteristicwithresponsefordevice|BleManager.writeCharacteristicWithResponseForDevice()},
- {@link #blemanagermonitorcharacteristicfordevice|BleManager.monitorCharacteristicForDevice()}

and other functions which are described in detail in documentation.
and other functions which are described in detail in documentation. You can also check our _example app_ which is available in the repository.
108 changes: 108 additions & 0 deletions docs/TUTORIALS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
### Monitoring device connection

`onDeviceDisconnected` method allows you to monitor the disconnection of a device, more about the method can be found {@link #here|BleManager.onDeviceDisconnected()}. Using it you can implement your own logic to handle the disconnection event. For example, you can try to reconnect to the device or show a notification to the user.

Note: connection will be monitored only when app is in foreground.

```ts
const setupOnDeviceDisconnected = (deviceIdToMonitor: String) => {
bleManagerInstance.onDeviceDisconnected(deviceIdToMonitor, disconnectedListener)
}

const disconnectedListener = (error: BleError | null, device: Device | null) => {
if (error) {
console.error(JSON.stringify(error, null, 4))
}
if (device) {
console.info(JSON.stringify(device, null, 4))

// reconnect to the device
device.connect()
}
}
```

### Reading and writing to characteristics

#### Prepare the connection with your device

The first thing you need to do is connect to your device. Once the connection is established you can only perform basic operations without the possibility of interacting with the services on the device. To be able to interact with the services on the device, so you need to call an additional command `device.discoverAllServicesAndCharacteristics()` because even though you know what service and characteristics are on the device, they all must be visible to the GATT client, which handles all operations.

```js
device
.connect()
.then(device => {
return device.discoverAllServicesAndCharacteristics()
})
.then(device => {
// A fully functional connection you can use, now you can read, write and monitor values
})
.catch(error => {
// Handle errors
})
```

#### Reading from a characteristic

To read a value from a characteristic, you need to call the `readCharacteristic` method on the device object. The method returns a promise that resolves to the characteristic value.

```js
device
.readCharacteristicForService(serviceUUID, characteristicUUID)
.then(characteristic => {
console.log('Read characteristic value:', characteristic.value)
})
.catch(error => {
console.error('Read characteristic error:', error)
})
```

#### Writing to a characteristic

To write a value to a characteristic, you need to call the `writeCharacteristicWithResponse` or `writeCharacteristicWithoutResponse` method on the device object. The method returns a promise that resolves when the write operation is completed.

```js
device
.writeCharacteristicWithResponseForService(serviceUUID, characteristicUUID, value)
.then(() => {
console.log('Write characteristic success')
})
.catch(error => {
console.error('Write characteristic error:', error)
})
```

### Connecting to a device that is already connected to the OS

If you want to connect to a device that isn't discoverable because it is already connected to the system, you can use the `getConnectedDevices` method to get a list of connected devices. Then you can use the `connect` method on the device object to connect to the device, after making sure that the device is not already connected.

```js
bleManagerInstance
.getConnectedDevices([serviceUUIDs])
.then(devices => {
const device = devices.find(d => d.id === deviceIdWeWantToConnectTo)

if (device && !device.isConnected) {
device.connect()
}
})
.catch(error => {
console.error('Get connected devices error:', error)
})
```

### Collecting native logs

If you encounter any issues with the library, you can enable native logs to get more information about what is happening under the hood. To enable native logs, you need to set the `logLevel` property on the BleManager instance to `LogLevel.Verbose`.

```js
bleManagerInstance.setLogLevel(LogLevel.Verbose)
```

#### Android

To collect native logs on Android, you can open the Logcat in Android Studio and set filters to `package:mine (tag:BluetoothGatt | tag:ReactNativeJS | RxBle)`.

#### iOS

To collect native logs on iOS, you can open the Xcode console.
Loading

0 comments on commit da2e860

Please sign in to comment.