CoreBluetooth state preservation issue: willRestoreState not called in iOS 7.1 CoreBluetooth state preservation issue: willRestoreState not called in iOS 7.1 objective-c objective-c

CoreBluetooth state preservation issue: willRestoreState not called in iOS 7.1


Okay, so I've had to delete two of my answers already to this question. But I think I've finally figured it out.

This comment is the key to your problem. Essentially, this centralManager:willRestoreState: only gets called if it's force closed by the OS while an outstanding operation is in progress with a peripheral (this does not include scanning for peripherals On further investigation, if you're scanning for a service UUID and the app is killed in the same way, or you've already finished connecting, it will in fact call your delegate).

To replicate:I have a peripheral using CoreBluetooth set up on my MacBook. I advertise on the peripheral, and have the central on my iPhone discover it. Then, leaving the OSX peripheral app running, kill your BT connection on your Mac and then initiate a connect from the central on your iOS device. This obviously will continuously run as the peripheral is non-reachable (apparently, the connection attempt can last forever as Bluetooth LE has no timeout on connections). I then added a button to my gui and hooked it up to a function in my view controller:

- (IBAction)crash:(id)sender{    kill(getpid(), SIGKILL);}

This will kill the app as if it was killed by the OS. Once you are attempting to connect tap the button to crash the app (sometimes it takes two taps).

Activating Bluetooth on your Mac will then result in iOS relaunching your app and calling the correct handlers (including centralManager:willRestoreState:).

If you want to debug the handlers (by setting a breakpoint), in Xcode, before turning BT on on your Mac, set a breakpoint and then select 'Debug > Attach to Process... > By Process Identifier or Name...'.

In the dialog that appears, type the name of your app (should be identical to your target) and click "Attach". Xcode will then say waiting for launch in the status window. Wait a couple seconds and then turn on BT on OSX. Make sure your peripheral is still advertising and then iOS will pick it up and relaunch your app to handle the connection.

There are likely other ways to test this (using notify on a characteristic maybe?) but this flow is 100% reproducible so will likely help you test you code most easily.


Had the same issue. From what I can work out, you need to use a custom dispatch queue when instantiating your CBCentralManager and your willRestoreState method will be triggered. I think this is due to async events not being handled by the default queue (when using "nil") when your app is started by the background recovery thread.

    ...    dispatch_queue_t centralQueue = dispatch_queue_create("com.myco.cm", DISPATCH_QUEUE_SERIAL);    cm = [[CBCentralManager alloc] initWithDelegate:self queue:centralQueue options:@{CBCentralManagerOptionRestoreIdentifierKey:@"cmRestoreID",CBCentralManagerOptionShowPowerAlertKey:@YES}];    ...


You need to move the CentralManager to its own queue.