Core Bluetooth State Preservation and Restoration Not Working, Can't relaunch app into background

和自甴很熟 提交于 2019-12-17 16:07:36

问题


I'm trying to make core bluetooth wake up the app even when it's not running.

As Apple stated, "Because state preservation and restoration is built in to Core Bluetooth, your app can opt in to this feature to ask the system to preserve the state of your app’s central and peripheral managers and to continue performing certain Bluetooth-related tasks on their behalf, even when your app is no longer running. When one of these tasks completes, the system relaunches your app into the background and gives your app the opportunity to restore its state and to handle the event appropriately."

I added following code to opt in to this feature:

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

But the callbacks when app is woke up never got triggered.

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

-(void)centralManager:(CBCentralManager *)central
      willRestoreState:(NSDictionary *)state {
}

These two are never called.

The way I'm testing this wake up function:

  1. I add "bluetooth central" in background mode in info.plist, so the BLE runs in background.

  2. start centralManager in my iphone No.1. start scan.

  3. press home and get out, play some memory heavy game, in the debug log i will see: "Terminated due to Memory Pressure. Process finished with exit code 0". This is to simulate how ios system terminate the background app due to memory pressure.

  4. start a beacon with another iphone No.2 and start broadcasting.

  5. result: those relaunch callbacks never get called.

Any ideas why this is not working? If it's an API problem, is there any other approach to relaunch your app into background with BLE when your phone gets close to BLE beacon? I've tried with using ibeacon to wake up the app, but core bluetooth central manager won't allow you to connect to ibeacon in background.

Thanks!


回答1:


CoreBluetooth state restoration only applies to connection and peripheral events. Solely relying on scanning is not currently supported.




回答2:


When you click home button to send app to background, it it suspended, and can handle Bluetooth delegates and run in background for 10s, this feature can be achieved solely by "add bluetooth central in background mode in info.plist", and does not use State Preservation & Restoration.

If your app is terminated by IOS, due to memory pressure, it can't handle bluetooth delegates anymore. In this case, if you used State Preservation & Restoration, your app can be relaunched to background to run again, also for only 10s. After 10s, it would move to suspended state. Only in this situation, CBCentralManager's willRestoreState can be triggered.

You can add code

kill(getpid(), SIGKILL);

to a button action, when you click the button, your app will be terminated by IOS just like killed by memory pressure, and then "willRestoreState" will be triggered.

Good luck.




回答3:


I also have this problem with background scanning for peripherals with known service UUIDs. Perhaps it is a bug in iOS. I find that iOS does relaunch the app when it discovers the peripheral, as can be seen by watching the console output from the device manager in XCode. The didFinishLaunchingWithOptions delegate gets called, but the call to the CBCentralManager's willRestoreState delegate is delayed until the user manually brings the app to the foreground.

It is as though the event loop on the main thread does not run, even though the app has been launched. For example, when adding the code:

dispatch_async(dispatch_get_main_queue(), ^{
  NSLog(@"Hello from the main thread");
});

to the didFinishLaunchingWithOptions delegate, the message is not displayed in the debug console until the app moves to the foreground.

My workaround is to use a custom queue running on a separate thread, rather than passing queue:nil when creating the CBCentralManager. This way the delegates are called while the app is still in the background.



来源:https://stackoverflow.com/questions/20529685/core-bluetooth-state-preservation-and-restoration-not-working-cant-relaunch-ap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!