When a CBManager is initalized with a background queue the delegate method didDiscoverPeripheral is called multiple times for multiple advertising packets. However, my testing is showing that the method is not called for every advertising packet sent by the peripheral. It is understandable that due to the nature of the BLE protocol, radio timing, etc. that some packets may go missing. However, I'm using a development peripheral that can be customized to deliver advertising packets at different intervals. At 100ms the delegate method is called once every 2-4 seconds. At 1000ms the delegate method is called more sproadically. Our application relies on broadcasted data encoded in the kCBAdvDataManufacturerData. Is there any way to achieve deterministic delegate calls for this purpose?
As both the scanning and advertising in BLE are discrete events (that is an iOS device does not scan continuously, but periodically), the probability of discovery for each advertising packet cannot be 1 (100%). Indeed, the probability curve of the chance of detection for a single packet is asymptotic, and every single packet cannot be guaranteed to be detected.
That said, Apple recommends certain advertising intervals to increase the probability of discovery.
To have a high probability of being discovered by an iOS device you should first use the recommended advertising interval of 20 ms for at least 30 seconds.
If it is not discovered within the initial 30 seconds, you can switch to using one of the following longer intervals to increase chances of discovery:
152.5 ms, 211.25 ms, 318.75 ms, 417.5 ms, 546.25 ms, 760 ms, 852.5 ms, 1022.5 ms, 1285 ms.
Any advertising interval outside these values will significantly reduce the chances of discovery of a peripheral. Detection of single packets still cannot be guaranteed.
In the field, there is no way of knowing what the scanning interval of an iOS device will be in order to even think of deterministic delegate callbacks. That will depend on the state of your app, the states of other apps using BLE, system processes, whether the device is actively being used or sitting idle, etc.
Additionally, when your app is in the background, the
CBCentralManagerScanOptionAllowDuplicatesKey scan option key is ignored, and multiple discoveries of an advertising peripheral are coalesced into a single discovery event.
Unfortunately, you cannot rely on the detection of every single advertising packet all the time.