Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CoreBluetooth "willRestoreState" - what exactly should be done there?

Tags:

I'm developing an application that needs to continuously run and track some peripheral characteristic.

All works fine in foreground.
It also works in background, but I'm not sure that I do it correctly.

I red many posts about state restoration and implementing willRestoreState, but many of them don't explicit tells you what to do when this method getting called.

The process that I'm making goes like this:

I'm creating a central manager using

myCentralManager =
        [[CBCentralManager alloc] initWithDelegate:self queue:nil
         options:@{ CBCentralManagerOptionRestoreIdentifierKey:
         @"myCentralManagerIdentifier" }];

From here I'm doing the regular flow of:
Waiting for central manager to get powered on (centralManagerDidUpdateState) -> Scan for my peripheral -> Connect to it -> Discover service -> Discover characteristic -> Subscribe to the charactristic -> Reading data

Then I kill my app using

kill(getpid(), SIGKILL);

I'm waiting a couple of seconds, and then starts advertising again from my peripheral.

Then I can see that the process is coming back to life, and my logs show that didFinishLaunchingWithOptions in AppDelegate is getting called.

I then restore the central manager like this:

 NSArray *identifiers = launchOptions[UIApplicationLaunchOptionsBluetoothCentralsKey];

   if (identifiers && identifiers.count > 0) {
        _centralManager = [[CBCentralManager alloc] initWithDelegate:self
                                                               queue:nil
                                                             options:@{CBCentralManagerOptionRestoreIdentifierKey:[identifiers objectAtIndex:0]}];
    } 

I can also see that willRestoreState and centralManagerDidUpdateState are getting called.

Here's where I'm lost. What should I do next? If I'm keep doing the regular flow (which I described above, All seems to work fine - and in the same way as above.

But - Am I doing the right thing?

Should I do something in willRestoreState? If yes, what I should do?

Thanks in advance!

like image 278
dor506 Avatar asked Jun 13 '16 18:06

dor506


1 Answers

basically you are handed back the peripheral which is already connected - you should save a reference to it and set yourself its delegate. this is my code, it is pretty straight forward:

   - (void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary<NSString *,id> *)dict
 {
      //get the handle to the peripheral already connected by the os and set ourselves as the delegate
      NSArray *peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey];
      if (peripherals.count > 0){
        CBPeripheral* pr = peripherals[0];
        // Set peripheral required values and start discovering services
        [pr setDelegate:self];
        [pr readRSSI];
        [pr discoverServices:nil];
      }
}
like image 141
talshahar Avatar answered Oct 10 '22 22:10

talshahar