2

I'm implementing Core Bluetooth background mode and have gotten to the willRestoreState method successfully. The system properly handles scanning and waking up my app on service advertisement and incoming data. However, if the device is already connected when the app is terminated (due to memory management), I cannot seem to reestablish functioning ownership of the peripheral. No delegate methods are called. Here is my willRestoreState method:

-(void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary<NSString *,id> *)state {
    NSArray *peripherals = state[CBCentralManagerRestoredStatePeripheralsKey];
    NSString* NFCName = @"ACR1255U-J1-001236";

    _centralManager = central;
    _centralManager.delegate = self;

    for(CBPeripheral* peripheral in peripherals) {
        if([peripheral.name isEqualToString:NFCName]) {
            NSLog(@"Restoring NFC Connection");
            _peripheral = peripheral;
            _peripheral.delegate = self;

            [_centralManager connectPeripheral:_peripheral options:nil];
            return;
        }
    }

    [_centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:@"FFF0"]] options:nil];
}

The Apple docs state that the app has to connect locally to the device, but _peripheral.state reads connected whether -connectPeripheral is called or not. Neither -centralManager:didConnectPeripheral nor -centralManager:didFailToConnectPeripheral: is called. Similarly [_peripheral readRSSI] does not result in -peripheral:didReadRSSI delegate method being called.

I can't seem to find full sample code for this functionality. If anyone has anything I can parse through to help troubleshoot, I'd appreciate that as well.

Thank you, SO

NewEndian
  • 559
  • 2
  • 16
  • Hi NewEndian, did you find a solution to this issue? I have the same issue. Thanks. – Alex Sep 01 '16 at 17:15
  • Hi, @newedian Please let me know if you have got any solution. I am also facing the same issue. Thanks. – Nik Feb 22 '17 at 04:51

1 Answers1

0

If the phone is already connected to the peripheral when the app is terminated, it won't call the centralManager:didConnectPeripheral callback, because it's already connected and Core Bluetooth has held that connection for you and has stored the details. It is up to you to restore the details of the connection in willRestoreState, as you correctly have done.

If it's already connected, the only thing I'm aware of that can wake it up is if the peripheral notifies or indicates or disconnects in which case if you've restored your peripheral correctly by setting the delegate the callback you're looking for is
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)error:(NSError *)
or
-(void)centralManager:(CBCentralManager *)didDisconnectPeripheral:(CBPeripheral *)error:(NSError *)
so I'd suggest you check the peripheral.connected state and only call connectPeripheral if peripheral.connected != CBPeripheralStateConnected or peripheral.connected != CBPeripheralStateConnecting

P_Dog
  • 208
  • 3
  • 12