Сохранение состояния Bluetooth BLE: CBCentralManager не будет обнаруживать службы в фоновом режиме
РЕДАКТИРОВАТЬ: После комментария @RobertVaessen я реализовал следующее, однако я все еще не могу обнаружить службы подключенного периферийного устройства.
-(void) centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary<NSString *,id> *)dict{
id tmpObj = [dict objectForKey:CBCentralManagerRestoredStatePeripheralsKey];
NSArray * keys = [dict allKeys];
NSString * message = @"";
for (int i=0; i<[keys count]; i++) {
NSString * stringTmp = keys[i];
message = [message stringByAppendingString:@";"];
message = [message stringByAppendingString:stringTmp];
}
// message contains "kCBRestoredScanServices and kCBRestoredPeripherals
if ([tmpObj isKindOfClass:[NSArray class]]) {
NSArray * peripheralsArray = (NSArray*)tmpObj;
for (int i=0; i<[peripheralsArray count]; i++) {
id objTmp = peripheralsArray[i];
if ([objTmp isKindOfClass:[CBPeripheral class]]) {
CBPeripheral * tmpPeripheral = (CBPeripheral*)objTmp;
tmpPeripheral.delegate = self;
[tmpPeripheral discoverServices: self.bleServices];
// It would reach this part of the code but not discover any services
}
}
}
}
Теперь сомнение заключается в следующем:
Я уже обнаружил службы, когда приложение находилось на переднем плане и сначала подключалось к периферийному устройству. Означает ли это, что, когда приложение снова разбудит приложение, CBCentralManager не сможет обнаружить службы?
Теоретический контекст:
Процесс сохранения состояния Bluetooth LE описан здесь (см. Раздел "Добавление поддержки сохранения и восстановления состояния"):
Что я пытаюсь сделать:
Я реализую приложение, которое использует сохранение состояния BLE для поддержания соединения с аппаратным аксессуаром (при работе в фоновом режиме).
Проблема, которую я получил, заключается в том, что всякий раз, когда iOS запускает мое приложение после события сохранения состояния BLE, мой CBCentralManager не может обнаружить службы. Странно, что периферийное оборудование "видит" соединение, но приложение iOS не может получить к нему доступ.
Другими словами: следующие методы в классе, реализующем делегат CBCentralManager, вызываются правильно, но мало что делают (см. Комментарии зеленого цвета ниже):
-(void) centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary<NSString *,id> *)dict{
NSArray * peripherals = [self.central retrieveConnectedPeripheralsWithServices:self.bleServices];
for (int i=0; i < peripherals.count; i++) {
CBPeripheral * peripheral = (CBPeripheral*) peripherals[i];
if (peripheral == nil) {
// Never happens
}
else{
// Always happens - also hardware thinks that the peripheral is connected
peripheral.delegate = self;
[peripheral discoverServices:self.bleServices];
// Does not discover any services ! <------------- ERROR!
}
}
-(void) peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
// Only gets called when [peripheral discoverServices:self.bleServices] is called whilst app is running (either in background or foreground).
}
PS: я спрашивал об этом также на форуме разработчиков Apple, но пока не получил ответа.
PPS: я также активировал фоновый режим в моем файле info.plist: