What I want is for my iOS device to be advertising a Bluetooth LE service all the time, even when the app isn\'t running, so that I can have another iOS device scan for it and f
The implementation can be founded here: https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/PerformingCommonPeripheralRoleTasks/PerformingCommonPeripheralRoleTasks.html#//apple_ref/doc/uid/TP40013257-CH4-SW5
Its very simply actually.
<CBPeripheralManagerDelegate>
@property (strong, nonatomic) CBPeripheralManager *peripheralManager;
...
- (NSDictionary*) advertiseNotBeacon {
CBUUID *myCustomServiceUUID = [CBUUID UUIDWithString:@"MY_UUID"];
CBMutableCharacteristic *myCharacteristic = [[CBMutableCharacteristic alloc] initWithType:myCustomServiceUUID
properties:CBCharacteristicPropertyRead | CBCharacteristicPropertyNotify
value:nil permissions:CBAttributePermissionsReadable];
CBMutableService *myService = [[CBMutableService alloc] initWithType:myCustomServiceUUID primary:YES];
myService.characteristics = @[myCharacteristic];
self.peripheralManager.delegate = self;
[self.peripheralManager addService:myService];
return @{CBAdvertisementDataServiceUUIDsKey : @[myService.UUID],
CBAdvertisementDataLocalNameKey: @"MY_NAME"
};
}
...
[self.peripheralManager startAdvertising:[self advertiseNotBeacon]];
Doing this, you will start advertising a peripheral service.
Now, if you want to keep the service running in background, read the documentation in this link: https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html#//apple_ref/doc/uid/TP40013257-CH7-SW1
Quick steps:
Open info.plist
Add a new par key/value
Required background modes
App shares data using CoreBluetooth
Apple says to ctrl + click on any key/value and add a add the following, but exactly the same as explained before.
UIBackgroundModes
bluetooth-peripheral
Dont forgot about the limitations of running the service in background:
Background advertisement is possible if you add the bluetooth-peripheral
backgrounding mode to the app's plist. Once you do that, your app will continue to receive the callbacks even if backgrounded.
The advertisement is a tricky beast as Apple implemented several optimizations to reduce the power consumption and these reduce the quality of the advertisement as soon as the app is backgrounded. Namely: the rate is reduced severely, the advertised services are not included and the local name is not included either. Once the app comes back to foreground, these restrictions are invalidated.
In the general case, this kind of backgrounded operation requires the app to be running. With iOS 7 the restoration process has been implemented that allows the OS to act on the app's behalf while it is terminated and restore the app when some transmission or other operation is imminent. This requires you to add the restoration key to the initialization options of the CBPeripheralManager
/CBCentralManager
. Starting your application once is still required but after that, iOS will continue to act as the BLE facade towards the centrals/peripherals.
UPDATE: I ran a loop on the Apple bluetooth-dev list as well with this question and found that Core Bluetooth managers were declared to be not able to restore after reboot. This is not described in any documentation but probably was mentioned in the WWDC videos. We should file a bug and replicate it to raise Apple's awareness.