CBPeripheral delegate callback of `peripheralIsReady(toSendWriteWithoutResponse:)` doesn't happen when app in background

My team has an app that uses BTLE heavily, and has been doing so successfully, including no issues continuing to receive data in the background and updating things in the app (for recording workouts).

We have a BTLE write queue that only tries to write when the CBPeripheral.canSendWriteWithoutResponse property is true, or when we get the notification from the system in peripheralIsReady(toSendWriteWithoutResponse:). This is used as a means to rate limit data transfer, as we transfer files, as well as require that packets always arrive in the correct order due to blob encoding.

However, we had a new requirement come in to periodically write data out to a connected peripheral. I noticed that as soon as the app was in the background, despite other delegate callbacks coming in, like didRecieveUpdatedValue:, neither the property canSendWriteWithoutResponse nor the delegate callback were called any longer. This meant our write queue didn't think it had permission to write, and packets would just stack up. The failure to deliver these updates didn't occur immediately after backgrounding, but did within 2-5s of backgrounding.

If, when in the background, I ignore the changing of that property, and instead just write the data to the peripheral, it works!

Can anyone explain why, despite other CBPeripheral callbacks happening when in the background, this one does not?

This is by design. the system will not wake up an app in order to deliver peripheralIsReady(toSendWriteWithoutResponse:). While you may sometimes see it called in the background if the app is already actively running for another reason, in most cases the app will be in a suspended state, and this call will not reach it. That is why you are seeing the callback a few seconds after being backgrounded, before the app gets suspended.


Argun Tekant /  DTS Engineer / Core Technologies

CBPeripheral delegate callback of `peripheralIsReady(toSendWriteWithoutResponse:)` doesn't happen when app in background
 
 
Q