I have CoreBluetooth set up on my app as a Central with the CBCentralManagerDelegate implemented to scan for peripherals with my service. I also have the
bluetooth-central
background mode declared in my Info.plist
file.Once connected, I discover services and read any characteristics I need. When a service is modified or added on the Peripheral side, I respond to the peripheral:didModifyServices: method, and rediscover services, which is working fine in the foreground.
My issue is that when my app is in the background, and the Peripheral I'm connected to adds a service, the peripheral:didModifyServices: method is not called. But ONLY that method is not called when my Central app is in the background. The other CBPeripheralDelegate methods (peripheral:didDiscoverServices:, peripheral:didDiscoverCharacteristicsForService:error:, etc) are all received when my app is in the background.
Is this behavior correct for the
bluetooth-central
background mode? Code below:CBCentralManagerDelegate:
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == .poweredOn {
central.scanForPeripherals(withServices: [primaryService], options: nil)
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
if let name = advertisementData[CBAdvertisementDataLocalNameKey] as? String {
print("Discovered peripheral " + name)
peripheral.delegate = self
connectedPeripherals.insert(peripheral)
central.connect(peripheral, options: nil)
}
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
connectedPeripherals.remove(peripheral)
}
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
connectedPeripherals.remove(peripheral)
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
peripheral.discoverServices(nil)
}
CBPeripheralDelegate:
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
for service in peripheral.services ?? [] {
if isRecognizedService(service) {
peripheral.discoverCharacteristics(nil, for: service)
}
}
}
// This is not called in the background!
func peripheral(_ peripheral: CBPeripheral, didModifyServices invalidatedServices: [CBService]) {
print("Peripheral services changed...")
peripheral.discoverServices(nil)
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
guard error == nil else {
print("Error discovering characteristics...")
return
}
guard let characteristics = service.characteristics, !characteristics.isEmpty else {
print("No characteristics found for service...")
return
}
for characteristic in service.characteristics ?? [] {
// Subscribe to characteristic changes, etc...
}
}