Skip to content

Commit 6b50aed

Browse files
committed
Demo: lazily create CBPeripheralManager only when starting advertising
Previously, PeripheralManager unconditionally instantiated CBPeripheralManager in init(), causing the system Bluetooth permission prompt on a fresh app launch. Move creation into startAdvertising() so the prompt only appears when the user explicitly chooses to use the peripheral advertising feature. This prevents the demo from appearing to trigger authorization automatically (via the library or otherwise). Also update the Start button enable logic to allow activation while the manager is still uninitialized.
1 parent a0f23d6 commit 6b50aed

2 files changed

Lines changed: 26 additions & 11 deletions

File tree

Demo/ReliaBLE Demo/ReliaBLE Demo/Peripheral/PeripheralManager.swift

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,32 +30,47 @@ import SwiftUI
3030
@Observable class PeripheralManager: NSObject, CBPeripheralManagerDelegate {
3131
var state: CBManagerState = .unknown
3232
var isAdvertising: Bool = false
33-
private var peripheralManager: CBPeripheralManager!
33+
private var peripheralManager: CBPeripheralManager?
3434
private var peripheralName: String = ""
3535
private var serviceUUID: CBUUID?
3636

37-
override init() {
38-
super.init()
39-
peripheralManager = CBPeripheralManager(delegate: self, queue: nil)
40-
}
41-
4237
func startAdvertising(name: String, serviceUUID: CBUUID) {
4338
self.peripheralName = name
4439
self.serviceUUID = serviceUUID
45-
peripheralManager.removeAllServices()
40+
41+
if peripheralManager == nil {
42+
// Create the manager only at the point the user requests advertising.
43+
// This avoids triggering a Bluetooth permission prompt on app launch.
44+
// If authorization is notDetermined, this will prompt the user.
45+
peripheralManager = CBPeripheralManager(delegate: self, queue: nil)
46+
// Actual advertising setup happens in peripheralManagerDidUpdateState once powered on.
47+
return
48+
}
49+
50+
guard peripheralManager?.state == .poweredOn else { return }
51+
peripheralManager?.removeAllServices()
4652
let service = CBMutableService(type: serviceUUID, primary: true)
47-
peripheralManager.add(service)
53+
peripheralManager?.add(service)
4854
}
4955

5056
func stopAdvertising() {
51-
peripheralManager.stopAdvertising()
57+
peripheralManager?.stopAdvertising()
5258
isAdvertising = false
5359
}
5460

5561
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
5662
state = peripheral.state
5763
if state != .poweredOn {
5864
isAdvertising = false
65+
return
66+
}
67+
68+
// If the user requested advertising before or while the manager was initializing,
69+
// proceed with adding the service now that we are powered on.
70+
if let uuid = serviceUUID, !isAdvertising {
71+
peripheral.removeAllServices()
72+
let service = CBMutableService(type: uuid, primary: true)
73+
peripheral.add(service)
5974
}
6075
}
6176

@@ -68,7 +83,7 @@ import SwiftUI
6883
CBAdvertisementDataLocalNameKey: peripheralName,
6984
CBAdvertisementDataServiceUUIDsKey: [serviceUUID!]
7085
]
71-
peripheralManager.startAdvertising(advertisementData)
86+
peripheralManager?.startAdvertising(advertisementData)
7287
}
7388

7489
func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?) {

Demo/ReliaBLE Demo/ReliaBLE Demo/Peripheral/PeripheralView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ struct PeripheralView: View {
9797
peripheralManager.startAdvertising(name: peripheralName, serviceUUID: uuid)
9898
}
9999
}
100-
.disabled(!isValid || peripheralManager.state != .poweredOn || peripheralManager.isAdvertising)
100+
.disabled(!isValid || peripheralManager.isAdvertising || (peripheralManager.state != .poweredOn && peripheralManager.state != .unknown))
101101
Button("Stop Advertising") {
102102
peripheralManager.stopAdvertising()
103103
}

0 commit comments

Comments
 (0)