I want to reconnect to BLE device after device is moved out/terminated by user or system/reboted in background mode.
I know that it's possible : - see this question with description
Question - How can i setup centralManager
for automatically reconnect to peripheral in background mode if app was terminated? Can someone describe step-by-step how it can be done?
Few word about current implementation:
I create centralManager with options like:
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{
CBCentralManagerOptionRestoreIdentifierKey: @"myCentralManagerIdentifier",
CBCentralManagerRestoredStatePeripheralsKey : @YES,
CBCentralManagerRestoredStateScanServicesKey : @YES,
CBCentralManagerRestoredStateScanOptionsKey : @YES
}];
After that i start to scan for BLE device
[self.centralManager scanForPeripheralsWithServices:[self discoverableCharacteristics] options:nil];
in - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
i connect to peripheral:
NSString *localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
[self.centralManager stopScan];
peripheral.delegate = self;
[self.centralManager connectPeripheral:peripheral options: @{
CBConnectPeripheralOptionNotifyOnNotificationKey : @YES
}];
After that i can discover services and characteristics - all looks like ok. When i discover characteristic and read/write data i cancelPeripheralConnection
in didDisconnect i reconnect to device
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error
{
[central connectPeripheral:peripheral options:nil];
}
i also implement centralManager:willRestoreState:
like:
NSArray *peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey];
for (CBPeripheral *peripheral in peripherals) {
[central connectPeripheral:peripheral options:nil];
peripheral.delegate = nil;
}
In plist. added required key App communicates using CoreBluetooth
.
Currently if i connected to device and terminate it - it relaunch automatically and connect to device - all it's ok, but if it's terminated again - nothing is happening.
Also if i moved out from peripheral and that come back - nothing happened.
Update
regarding point 5 - my fall - should use this key with connectPeripheral
in WillRestoreState:
NSArray *peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey];
if (!peripherals.count) {
peripherals = [central retrievePeripheralsWithIdentifiers:[self discoverableCharacteristics]];
}
if (peripherals.count) {
for (CBPeripheral *peripheral in peripherals) {
[central connectPeripheral:peripheral options:@{
CBCentralManagerRestoredStatePeripheralsKey : @YES,
CBCentralManagerRestoredStateScanServicesKey : @YES,
CBCentralManagerRestoredStateScanOptionsKey : @YES
}];
}
} else {
[self startScanning];
}
Current result - app will relaunched if it not swiped out from tray. I use my mac as a peripheral, so some times when i not launch app that make role of peripheral central can connect to mac itself not to required service.
Another question - are it's good option to reconnect to peripheral while lost connection for keeping connection like:
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error
{
[central connectPeripheral:peripheral options:@{
CBCentralManagerRestoredStatePeripheralsKey : @YES,
CBCentralManagerRestoredStateScanServicesKey : @YES,
CBCentralManagerRestoredStateScanOptionsKey : @YES
}];
}
Also try to change notify characteristic on peripheral and read it on device. If all done in foreground - all works perfect, but in case connection was done in background some times didUpdateValueForCharacteristic
not called at all, but didUpdateNotificationStateForCharacteristic
is called with no error - this mean (i think) that something was done wrong by my side. Maybe u can advice where problem can be
And one more question - is there is some restriction in writing data to characteristics? because in apple sample it's setuped to 20 bytes.