Skip to content

petrbela/react-native-peripheral

Repository files navigation

react-native-peripheral

React Native library for building BLE peripherals.

Note: If you want to write a BLE Central application (that connects to BLE peripherals such as a watch or heart rate monitor), check out react-native-ble-plx or react-native-ble-manager instead.

Installation

Using npm:

npm install --save react-native-peripheral

or using yarn:

yarn add react-native-peripheral

Then follow the instructions for your platform to link react-native-peripheral into your project:

iOS

React Native 0.60 and above

Linking is automatic. Just run pod install in the ios directory.

React Native 0.59 and below

Run react-native link react-native-peripheral to link the react-native-peripheral library.

If you're still managing dependencies through Xcode projects, or if the above didn't work:

  1. In XCode, in the project navigator, right click LibrariesAdd Files to [your project's name]
  2. Go to node_modulesreact-native-peripheral and add RnBlePeripheral.xcodeproj
  3. In XCode, in the project navigator, select your project. Add libRnBlePeripheral.a to your project's Build PhasesLink Binary With Libraries
  4. Run your project (Cmd+R)
Android

Android support is not implemented yet.

Usage

import Peripheral, { Service, Characteristic } from 'react-native-peripheral'

Peripheral.onStateChanged(state => {
  // wait until Bluetooth is ready
  if (state === 'poweredOn') {
    // first, define a characteristic with a value
    const ch = new Characteristic({
      uuid: '...',
      value: '...', // Base64-encoded string
      properties: ['read', 'write'],
      permissions: ['readable', 'writeable'],
    })

    // add the characteristic to a service
    const service = new Service({
      uuid: '...',
      characteristics: [ch],
    })

    // register GATT services that your device provides
    Peripheral.addService(service).then(() => {
      // start advertising to make your device discoverable
      Peripheral.startAdvertising({
        name: 'My BLE device',
        serviceUuids: ['...'],
      })
    })
  }
})

Note: addService and startAdvertising are conceptually independent events. A BLE peripheral can start advertising regardless of whether if has defined any services. Conversely, you can define services which can be used by previously defined clients. However, in most cases, you'll want to do both.

To end a session, you can call Peripheral.stopAdvertising. You can also check if you're currently advertising with Periperheral.isAdvertising.

Dynamic Value

If you want to change the characteristic value dynamically, instead of providing value, implement onReadRequest and onWriteRequest (if your characteristic supports read and write operations):

new Characteristic({
  uuid: '...',
  properties: ['read', 'write'],
  permissions: ['readable', 'writeable'],
  onReadRequest: async (offset?: number) => {
    const value = '...' // calculate the value
    return value // you can also return a promise
  },
  onWriteRequest: async (value: string, offset?: number) => {
    // store or do something with the value
    this.value = value
  },
})

Notifications

If the value in your characteristic changes frequently, BLE clients may want to subscribe to be notified about the changes. Subscription logic is handled for you automatically, you just need to do two things:

  1. Include notify in the list of properties:

    const ch = new Characteristic({
      // ...
      properties: ['notify', ...]
    })
  2. Trigger notify with a value to send to subscribed clients:

    const value = '...'
    ch.notify(value)
  3. (optional) You may also track when clients subscribe to notifications, for example to avoid recomputing the value when no one is listening. This is optional since a call to notify will deliver to all subscribers by default, and silently no-op when there are none.

    const listeners = 0
    const ch = new Characteristic({
      // ...
      onSubscribe() {
        listeners++;
      }
      onUnsubscribe() {
        listerers--;
      }
    })
    
    // sometime later
    if (listeners) {
      const value = '...' // calculate value
      ch.notify(value)
    }

Base64

This library expects the value to be a Base64-encoded string.

Depending on your use case, you may want to add a library to help you convert to Base64:

  • If you work with binary data, we recommend you internally store an ArrayBuffer or Uint8Array and convert it using base64-arraybuffer or base64-js
  • For dealing with complex binary structures, try jBinary
  • If you want to send text data, we recommend you use base64.js