Core Bluetooth State Restoration

2019-02-16 05:05发布

I am working on an app that reacts on disconnects of peripherals and I am now trying to adopt the ne state preservation and restoration introduced in iOS 7.

I did everything like the documentation says, means:

  1. I added the background mode for centrals.

  2. I always instantiate my central manager with the same unique identifier.

  3. I implemented the centralManager:willRestoreState: method.

When my App moves to background I kill it in the AppDelegate callback with an kill(getpid(), SIGKILL);. (Core Bluetooth State Preservation and Restoration Not Working, Can't relaunch app into background)

When I now disconnect a peripheral by removing the battery my app is being waked up as expected and launchOptions[UIApplicationLaunchOptionsBluetoothCentralsKey] contains the correct identifier BUT the centralManager:willRestoreState: was not called. Only if I disconnect another peripheral this method gets called.

1条回答
劳资没心,怎么记你
2楼-- · 2019-02-16 05:37

This is how I have it:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{

    NSArray *peripheralManagerIdentifiers = launchOptions[UIApplicationLaunchOptionsBluetoothPeripheralsKey];

    if (peripheralManagerIdentifiers) {

        // We've restored, so create the _manager on the main queue
        _manager = [[CBPeripheralManager alloc] initWithDelegate:self
                                                          queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
                                                        options:@{CBPeripheralManagerOptionRestoreIdentifierKey:@"YourUniqueIdentifier"}];

    } else {

        // Not restored so just create as normal
        manager = [[CBPeripheralManager alloc] initWithDelegate:self
                                                          queue:nil
                                                        options:@{CBPeripheralManagerOptionRestoreIdentifierKey:@"YourUniqueIdentifier"}];

    }
return YES;
}

And then:

- (void)peripheralManager:(CBPeripheralManager *)peripheral
         willRestoreState:(NSDictionary *)dict
{


    // This is the advertisement data that was being advertised when the app was terminated by iOS
    _advertisementData = dict[CBPeripheralManagerRestoredStateAdvertisementDataKey];

    NSArray *services = dict[CBPeripheralManagerRestoredStateServicesKey];

    // Loop through the services, I only have one service but if you have more you'll need to check against the UUID strings of each
    for (CBMutableService *service in services) {

        _primaryService = service;

        // Loop through the characteristics
        for (CBMutableCharacteristic *characteristic in _primaryService.characteristics) {

            if ([characteristic.UUID.UUIDString isEqualToString:CHARACTERISTIC_UUID]) {

                _primaryCharacteristic = characteristic;

                NSArray *subscribedCentrals = characteristic.subscribedCentrals;

                // Loop through all centrals that were subscribed when the app was terminated by iOS
                for (CBCentral *central in subscribedCentrals) {

                    // Add them to an array
                    [_centrals addObject:central];

                }
            }
        }
    }
}
查看更多
登录 后发表回答