CoreBluetooth state preservation issue: willRestoreState not called in iOS 7.1
Hey all. I’ve been working on a Bluetooth LE project for the past few weeks, and hit a roadblock. I have been unable to get state restoration working properly in iOS 7 / 7.1. I’ve followed (I think) all of the steps Apple lays out, and got some clues on other stack overflow posts.
- I added the proper bluetooth permissions to the plist
- when I create my central manager, I give it a restore Identifier key.
- I always instantiate the CM with the same key
- I added the willRestoreState function to the CM delegate
My Test Case:
- Connect to peripheral
- Confirm connection
- Simulate Memory Eviction (kill(getpid(), SIGKILL);)
- Transmit Data
Results iOS 7:
The app would respond in the AppDelegate didFinishLaunchingWithOptions function, but the contents of the NSArray inside of launchOptions[UIApplicationLaunchOptionsBluetoothCentralsKey] was always an empty array.
Results on iOS 7.1:
Progress! I can see my CentralManager key in the UIApplicationLaunchOptionsBluetoothCentralsKey array 100% of the time, but willRestoreState is never called.
Code:
//All of this is in AppDelegate for testing
@import CoreBluetooth;
@interface AppDelegate () <CBCentralManagerDelegate, CBPeripheralDelegate>
@property (readwrite, nonatomic, strong) CBCentralManager *centralManager;
@end
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{CBCentralManagerOptionRestoreIdentifierKey:@“myCentralManager”}];
//Used to debug CM restore only
NSArray *centralManagerIdentifiers = launchOptions[UIApplicationLaunchOptionsBluetoothCentralsKey];
NSString *str = [NSString stringWithFormat: @"%@ %lu", @"Manager Restores: ", (unsigned long)centralManagerIdentifiers.count];
[self sendNotification:str];
for(int i = 0;i<centralManagerIdentifiers.count;i++)
{
[self sendNotification:(NSString *)[centralManagerIdentifiers objectAtIndex:i]];
}
return YES;
}
- (void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary *)state {
activePeripheral = [state[CBCentralManagerRestoredStatePeripheralsKey] firstItem];
activePeripheral.delegate = self;
NSString *str = [NSString stringWithFormat: @"%@ %lu", @"Device: ", activePeripheral.UUID];
[self sendNotification:str];
}
//sendNotification is a func that creates a local notification for debugging when device connected to comp
When I run the tests, didFinishLaunchWithOptions is called 100% when my BLE device communicates to the phone when the app is not in memory, but willRestoreState is never called.
Any and all help would be great! thanks!