Skip to content

Commit dfcb901

Browse files
committed
fix(ios): lazy init of ble manager to avoid prompting bluetooth permission on app start
1 parent e8326ff commit dfcb901

File tree

3 files changed

+27
-16
lines changed

3 files changed

+27
-16
lines changed

README.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -108,26 +108,27 @@ await BluetoothStateManager.requestToDisable();
108108

109109
An example is under `example/App.tsx`
110110

111-
| Method | Return Type | OS | Description |
112-
| ------------------------------------------------------- | ------------------------- | ------------ | ---------------------------------------------------------------- |
113-
| [useBluetoothState()](#usebluetoothstate) | `BluetoothState` | Android, iOS | Hook that returns the current state of the bluetooth service. |
114-
| [getState()](#getstate) | `Promise<BluetoothState>` | Android, iOS | Returns the current state of the bluetooth service. |
115-
| [getStateSync()](#getstatesync) | `BluetoothState` | Android, iOS | Returns the current state synchronous of the bluetooth service. |
116-
| [addListener(listener, emitCurrentState)](#addlistener) | `Subscription` | Android, iOS | Listen for bluetooth state changes. |
117-
| [openSettings()](#opensettings) | `Promise<null>` | Android, iOS | Opens the bluetooth settings. Please see below for more details. |
118-
| [requestToEnable()](#requesttoenable) | `Promise<void>` | Android | Show a dialog that allows the user to turn on Bluetooth. |
119-
| [requestToDisable()](#requesttodisable) | `Promise<void>` | Android | Show a dialog that allows the user to turn off Bluetooth. |
111+
| Method | Return Type | OS | Description |
112+
| ---------------------------------------------------------------- | ------------------------- | ------------ | ---------------------------------------------------------------- |
113+
| [useBluetoothState(enabled: boolean = true)](#usebluetoothstate) | `BluetoothState` | Android, iOS | Hook that returns the current state of the bluetooth service. |
114+
| [getState()](#getstate) | `Promise<BluetoothState>` | Android, iOS | Returns the current state of the bluetooth service. |
115+
| [getStateSync()](#getstatesync) | `BluetoothState` | Android, iOS | Returns the current state synchronous of the bluetooth service. |
116+
| [addListener(listener, emitCurrentState)](#addlistener) | `Subscription` | Android, iOS | Listen for bluetooth state changes. |
117+
| [openSettings()](#opensettings) | `Promise<null>` | Android, iOS | Opens the bluetooth settings. Please see below for more details. |
118+
| [requestToEnable()](#requesttoenable) | `Promise<void>` | Android | Show a dialog that allows the user to turn on Bluetooth. |
119+
| [requestToDisable()](#requesttodisable) | `Promise<void>` | Android | Show a dialog that allows the user to turn off Bluetooth. |
120120

121121
---
122122

123-
### useBluetoothState()
123+
### useBluetoothState(enabled: boolean = true)
124124

125125
Hook that returns the current state of the bluetooth service.
126126

127127
```tsx
128128
import { useBluetoothState } from "react-native-bluetooth-state-manager";
129129

130-
const bluetoothState = useBluetoothState();
130+
const enabled = true; // default true
131+
const bluetoothState = useBluetoothState(enabled);
131132
switch (bluetoothState) {
132133
case "Unknown":
133134
case "Resetting":

packages/react-native-bluetooth-state-manager/ios/HybridBluetoothStateManager.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class HybridBluetoothStateManager: HybridBluetoothStateManagerSpec {
5757
let listener = Listener(callback: callback)
5858
let key = UUID().uuidString
5959
listeners[key] = listener
60+
ensureManagerInitialized()
6061
return key
6162
}
6263

@@ -67,22 +68,24 @@ class HybridBluetoothStateManager: HybridBluetoothStateManagerSpec {
6768
var centralManager: CBCentralManager!
6869
var bManager: CentralManager!
6970

70-
override init() {
71-
super.init()
72-
self.bManager = CentralManager.init { state in
71+
private func ensureManagerInitialized() {
72+
guard bManager == nil else { return }
73+
bManager = CentralManager { state in
7374
for listener in self.listeners.values {
7475
listener.callback(state)
7576
}
7677
}
7778
}
7879

7980
func getState() throws -> NitroModules.Promise<BluetoothState> {
81+
ensureManagerInitialized()
8082
return Promise.async {
8183
return self.bManager.getState()
8284
}
8385
}
8486

8587
func getStateSync() throws -> BluetoothState {
88+
ensureManagerInitialized()
8689
return self.bManager.getState()
8790
}
8891

packages/react-native-bluetooth-state-manager/src/useBluetoothState.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import { useSyncExternalStore } from 'react'
2-
import { BluetoothStateManager } from './BluetoothStateManager'
2+
import {
3+
BluetoothStateManager,
4+
type BluetoothState,
5+
} from './BluetoothStateManager'
6+
7+
export const useBluetoothState = (enabled = true): BluetoothState => {
8+
if (!enabled) {
9+
return 'Unknown'
10+
}
311

4-
export const useBluetoothState = () => {
512
return useSyncExternalStore(
613
(cb) => {
714
const remove = BluetoothStateManager.addListener(cb)

0 commit comments

Comments
 (0)