iOS核心蓝牙状态保存和恢复问题

时间:2014-02-16 14:00:38

标签: ios objective-c bluetooth core-bluetooth

我对iOS 7上的核心蓝牙的状态保存和恢复有疑问。

我似乎无法让它正常工作。我已经按照苹果在他们的核心蓝牙文档中提到的每个指导以及状态保存的一般文档。

例如:Core Bluetooth Background Processing for iOS Apps和此处:iOS State Preservation and Restoration

我可以在设备上使用常规状态保存(用于视图控制器和对象等),但不能用于蓝牙管理器。

据我所知,cheklist看起来像这样:

  1. 通过在选项词典中为键 CBCentralManagerOptionRestoreIdentifierKey 分配恢复标识符来分配和初始化中央管理器对象时,选择保留和恢复。

  2. 在系统重新启动应用程序后,重新实例化所有中央管理器对象。当应用程序:didFinishLaunchingWithOptions:被调用时,这在app delegate中完成。在这里,我应该在选项字典中查找 UIApplicationLaunchOptionsBluetoothCentralsKey ,然后使用该密钥重新安排CBManager。在这里出现问题,因为该密钥从来没有任何标识符,因此我无法重新启用它。

  3. 实施适当的恢复委托方法。我也做了这一步,但由于经理从未重新实例化,我从未收到过这个委托回调。

  4. 该应用程序在后台运行良好,我也已按照该部分的所有步骤进行操作。

    现在,说了这么多,我并不确定如何测试这个,这可能是这个问题的一部分。我现在这样做的方法是按下iOS设备上的主页按钮(执行设备),这样它就可以将应用程序置于后台并返回主屏幕。在这样做时,我可以通过查看我的日志输出来判断所有常规状态保存调用是否实现。在此之后,我通过按Xcode中的停止按钮退出应用程序以终止后台进程。我现在通过Xcode重新启动应用程序,现在我再次看到正在执行的所有常规状态保存代码,除了蓝牙管理器之外的所有状态都恢复状态。

    如果这是错的,请告诉我。但总的来说,我对此非常困惑,因为它在核心蓝牙文档中说,只有当“你的应用程序被系统重新启动”时才会进行保存。那个的真实意义是什么?我还在Apple开发者论坛上看了一篇文章,自iOS 7以来,如果用户手动杀死我正在做的应用程序,操作系统现在不会以任何理由重新启动应用程序。

    对此有任何帮助将不胜感激!

    / A

3 个答案:

答案 0 :(得分:6)

当您单击主页按钮将应用程序发送到后台时,它会暂停,并且可以处理蓝牙代表并在后台运行10秒,此功能可以通过“在info.plist中的后台模式中添加蓝牙中心”来实现,并且不要使用State Preservation&恢复。

如果您的应用由于内存压力而被IOS终止,它将无法再处理蓝牙代表。在这种情况下,如果您使用了State Preservation&恢复,您的应用程序可以重新启动到后台再次运行,也只有10秒。 10秒后,它将进入暂停状态。 只有在这种情况下,才能触发CBCentralManager的willRestoreState。

您可以添加代码

[kill(getpid(), SIGKILL);]

按钮操作,当您单击按钮时,您的应用程序将被IOS终止,就像被内存压力所杀,然后“willRestoreState”将被触发。

祝你好运。

答案 1 :(得分:4)

首先,请注意视图控制器的状态保留与核心蓝牙管理器的恢复无关。

重要:恢复不适用于扫描,静态特征以及通常不会生成与连接相关的事件的任何用例。

现在的步骤:

  1. 确保测试应用中的以下任何内容:
    • 外围经理正在做广告
    • 外围经理已连接中心
    • 中心正在尝试连接外围设备
    • central连接到某些外围设备
  2. 使用此应用程序杀死您的应用:https://github.com/ddaddy/BackgroundKill(感谢ddaddy,给回购广告明星)
    1. 切换到杀手级应用
    2. 开始查杀过程并等待系统终止
    3. 你的app现已被杀
  3. 做一些连接事件
    • (经测试的外围设备)订阅外围设备上的特征
    • (经过测试的外围设备)启动关于动态特性的读取请求
    • (经过测试的中心)使连接请求成功
    • (经测试的中央)更新外围设备上的订阅特征
  4. 根据您要测试的内容,请考虑列表中的适用点。在测试的应用程序中使用日志记录,并在组织者中查看日志以查看随时间发生的情况。

答案 2 :(得分:1)

我能够在后台扫描(连同和传输数据)。您的应用终止方式与iOS将保留和恢复您的Core Bluetooth Manager之间存在重大差异。

添加"应用程序使用CoreBluetooth进行通信"到"所需的背景模式"在Info.plist中涵盖了大多数情况。您的中央管理员将继续在后台工作 - 无论是当用户按下主页按钮还是锁定电话(或两者)。但是你永远不会得到" willRestoreState"在这些情况下代理呼叫,因为您的中央管理员仍在由您的应用程序处理(它仍在内存中)。

保存和恢复仅在一种情况下生效 - 由于内存限制,您的应用已被iOS 终止。当你的应用程序在后台运行时,最简单的方法是强制测试它以加载3-4个内存密集型游戏。如果您查看设备控制台,则需要等待此消息:

"Apr  4 13:16:47 Michaels-iPhone SpringBoard[58] <Warning>: Application 'UIKitApplication:com.oculeve.TearBud[0x6df4]' was killed by jetsam.”

此时iOS将接管您的中央管理员。如果是扫描,它将继续扫描,如果它连接到外围设备,它将继续连接。如果您收到中央管理员委托调用(didDiscoverPeripheral,didUpdateValueForCharacteristic),iOS将在后台再次启动您的应用程序。 此时您将获得willRestoreState委托调用。此时,您的应用程序将返回内存,并将按上述方式工作。请注意,如果您连接到设备,则可能需要在willRestoreState中进行一些恢复。这些都包含在WWDC 2013核心蓝牙视频演示中。

如果您从系统托盘中手动关闭应用程序(在应用程序上向上滑动),那么恢复/保存不会的效果似乎很明显。我假设Apple的推理是在这种情况下,用户明确关闭应用程序,所有蓝牙通信应该停止。用户重启手机也是如此。我假设这是因为重启基本等于向上滑动以关闭系统托盘中的所有应用程序。如果达到这一点,只有在用户再次打开您的应用程序后才能重新连接。

需要指出的是,仅仅因为您的应用在系统托盘中并不意味着它在内存中。

为什么Apple不会在文档中告诉您这一点超出我的范围。