如何触发Core Bluetooth状态保存和恢复

How to trigger Core Bluetooth state preservation and restoration

State Preservation and Restoration 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. In the case of the home security app described above, the system would monitor the connection request, and re-relaunch the app to handle the centralManager:didConnectPeripheral: delegate callback when the user returned home and the connection request completed.

如何触发它并测试代码?

我有一个带有服务的配件。我有一个扫描服务的应用程序,我选择了状态保存。但是我不确定如何从逻辑上测试它,因为我不知道触发它需要什么。这些是我尝试失败的选项:

A - kill the app from Xcode

B - kill the app manually

C - power off the phone

D - something else

在所有这些选项中,我尝试转到 Xcode -> 设备 并查看日志,但没有看到任何状态恢复日志。

谢谢

NB 感谢 user1785784 for sharing Apple's QA1962 - Conditions Under Which Bluetooth State Restoration Will Relaunch An App 在 iOS 11 中描述了新的蓝牙行为。虽然我认为这篇文档应该被认为是这个问题的答案它错误地声称 iOS 10 重新启动已被强制退出的应用程序。 (我没有在 iOS 10 设备上测试过,但它会偏离 iOS 9。有人可以确认吗?)。

从任务切换器手动终止应用程序 (B),确保您的应用程序不会自动启动,直到用户再次明确打开它。

C也不行,我想只有VOIP应用程序会在重启后自动启动,然后只有在设备解锁后才会启动。

我不认识任何D。

我用A。

首先,要实现蓝牙状态恢复,请确保您已经

  1. added bluetooth-central 作为 UIBackgroundModes 你的 Info.plist
  2. 在启动 CBCentralManager
  3. 时设置 CBCentralManagerOptionRestoreIdentifierKey
  4. 在您的 CBCentralManager 委托中实现了 -(void)centralManager:willRestoreState: 回调。

那么您就可以测试状态恢复了:

  1. 让应用程序进入某个已知状态(比如蓝牙已打开,某些设备 connected/connecting)
  2. 在 Xcode
  3. 中终止应用程序
  4. 查看日志或set a launch breakpoint
  5. 更改蓝牙状态,例如经过
    • 切换航空公司模式
    • 将蓝牙设备带出范围(为了避免走路,我把我的放在 conductor/Faraday Cage/coffee 锅里)
    • 将设备带回范围内
    • 与设备交互,例如按一个 button/having 一个脉冲
  6. 看着你的状态恢复代码被调用

注意: application:didFinishLaunchingWithOptions: 将首先被调用,您必须立即如上所述初始化您的 CBCentralManager然后会调用centralManager:willRestoreState:

最近在 Apple Tech 的帮助下解决了这个问题。 Also given/have a nice link that shows the different ways to cause the app to restart without user intervention.

我是通过以下 swift 代码片段导致应用程序突然崩溃来做到这一点的。这会导致应用重新启动并调用 'willRestoreState' 回调。

DispatchQueue.main.asyncAfter(deadline: .now() + 5)
        {
            print("Killing app")
            // CRASH
            if ([0][1] == 1){
                exit(0)
            }
            exit(1)
        }