The subject says it all, really. Documentation, insofar as it exists at all, suggests that apps written against the CoreBluetooth framework running on iOS devices can add \"
Nobody seemed to know, so I bought an iOS developer account and ran some experiments. Here's what I found:
When running in the foreground, you can start a scan using CBCentralManager::scanForPeripheralsWithServices. Your scan can be restricted to devices advertising a particular service, or unrestricted (pass nil for that call's parameter). It can also allow or disallow duplicates; in the former case you'll get a didDiscoverPeripheral callback every time the iPhone receives an advertisment packets; in the latter you'll only get one callback per device found.
When you enter the background, the rules appear to be as follows:
I don't know whether connect attempts to nonconnectable devices (e.g. BLE Advertisers, like those implementing the proximity profile) is good enough as my example devices are connectable. However at least for connectable devices, this scan/connect/disconnect/scan procedure suffices to poll for a device's presence in the background.
The above results were gathered using an iPhone 4S running iOS 5.0.1
I've just learnt background mode for BLE devices on iOS8.3 & 8.4 and have found some differences from above:
if I start
[centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:kServiceUUID]] options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @YES }];
from
- (void)applicationDidEnterBackground:(UIApplication *)application
I found enumeration returns the same device every call with different RSSI, so CBCentralManagerScanOptionAllowDuplicatesKey isn't ignored.
It is also good to note the behavior of backgrounding and CoreBluetooth related to the iBeacons, although Apple likes to think of this as a CoreLocation functionality:
When notifications for an iBeacon region are turned on, they will notify the user of region entry or exit. These notifications can be made to depend on whether the display is on or off. These notifications will work even when the app requesting notifications is in the background. (This much is clear in the documentation).
Not so obvious: If you use the iBeacon ranging API, then your app has to be in the foreground. It does not explicitly say this in the documentation-- in fact, one can be mislead to think that ranging should work in the background from the documentation. However, an Apple engineer clarifies this in a post buried somewhere in a long thread on the Apple developer forum, and I've seen this fail too. Ranging will work only in the foreground.
One can discover other services being advertised by a peripheral advertising iBeacons. But this will work only in the foreground. So if you want the central to be notified of proximity using iBeacons, and then do some other transactions using other BLE-based services, this will work, but only in the foreground. It will not work in the background. For transactions with BLE-based services in the background, the advertisement has to be a regular BLE advertisement, not an iBeacon. You cannot use an iBeacon advertisement to help the discovery process in the background, and then switch to using BLE-services in the background. (I would have very much liked this to work, but no dice).
In addition to Chris's answer:
peripheral:didUpdateValueForCharacteristic:error:
) from the peripheral in background, even after 10minutes.So when you want to continuously run in background you have 2 options:
Later should be the "Event backgrounding" from WWDC 2012 Core Bluetooth videos https://developer.apple.com/videos/wwdc/2012/ But the former looks like a hack, I don't want to rely on it.
I tested this on iPhone5, iOS6.1.4
Apple finally released the Core Bluetooth Programming Guide and here's the official note about
Core Bluetooth Background Processing for iOS Apps