【问题标题】:How to trigger Core Bluetooth state preservation and restoration如何触发Core蓝牙状态保存和恢复
【发布时间】:2016-01-12 19:47:20
【问题描述】:

国家保护和恢复因为国家保护和 Core Bluetooth 内置恢复功能,您的应用可以选择加入 要求系统保留应用程序中心状态的功能 和外围经理,并继续执行某些 代表他们完成与蓝牙相关的任务,即使您的应用程序没有 运行时间更长。 当其中一项任务完成时,系统 将您的应用重新启动到后台并为您的应用提供 有机会恢复其状态并处理事件 就上述家庭安全应用而言, 系统将监控连接请求,并重新启动 处理 centralManager:didConnectPeripheral: 委托的应用程序 用户回家和连接请求时的回调 完成。

如何触发并测试代码?

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

A - kill the app from Xcode

B - kill the app manually

C - power off the phone

D - something else

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

谢谢

【问题讨论】:

    标签: ios xcode bluetooth state-restoration ble-state-preservation


    【解决方案1】:

    NB 感谢 user1785784 分享 Apple 的 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 时设置CBCentralManagerOptionRestoreIdentifierKey
    3. 在您的 CBCentralManager 委托中实现了 -(void)centralManager:willRestoreState: 回调。

    然后你就可以测试状态恢复了:

    1. 让应用程序进入某个已知状态(例如蓝牙已打开,某些设备已连接/正在连接)
    2. 在 Xcode 中杀死应用程序
    3. 观看日志或set a launch breakpoint
    4. 更改蓝牙状态,例如经过
      • 切换航空公司模式
      • 蓝牙设备超出范围(为避免走路,我将我的设备放在导体/法拉第笼/咖啡壶中)
      • 将设备恢复到范围内
      • 与设备交互,例如按下按钮/脉搏
    5. 注意调用您的状态恢复代码

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

    【讨论】:

    • @RhytmicFistman 非常感谢您的回答。我正在使用您的方法。但是我不确定我是否正确实现了状态恢复代码。我需要在 AppDelegate didFinishLaunchingWithOptions 中实例化一个新的 CBCentralManager 对象吗?能否分享一些简单的示例代码?
    • PS:此外,每当我使用 NSLog 时,我都看不到设备日志中记录的消息(当应用程序被终止时)。我只能看到“BTLE 扫描仪开机”之类的东西。
    • 对不起,我忘了说你需要给你的Info.plist添加一个后台模式。答案已更新。
    • 我参加聚会有点晚了。但是,您也可以通过运行以下命令以编程方式终止应用程序:exit(0)。这应该模拟操作系统杀死应用程序。如果您的设备随后发现它在被杀死之前正在扫描的 perisperhal,则应该重新启动它。要查看日志,我使用 os.log(统一日志记录)。这允许我查看 Mac 控制台应用程序中的日志。你可以给你的日志一个标签,你可以在控制台中过滤它。
    • 要使用 OS Log 进行记录,首先必须导入 os.log,然后调用以下命令: let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "background-scan") os_log("Your message", log: log) 类别是您在控制台应用程序中过滤的内容
    【解决方案2】:

    最近在 Apple Tech 的帮助下才发现这一点。 Also given/have a nice link that shows the different ways to cause the app to restart without user intervention.

    我通过使用以下 swift 代码的 sn-p 使应用程序突然崩溃来做到这一点。这会导致应用重新启动并调用“willRestoreState”回调。

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

    【讨论】:

    • 感谢您提供这个非常重要的链接!
    • 这确实是一个非常重要的链接。谢谢你。
    猜你喜欢
    • 2013-08-31
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-14
    • 2016-01-12
    相关资源
    最近更新 更多