【问题标题】:iOS stops waking up the app upon incoming BLE connection from peripheraliOS 在从外围设备传入 BLE 连接时停止唤醒应用程序
【发布时间】:2016-09-26 09:29:56
【问题描述】:

我们有一个 BLE 外围设备,每小时连接到手机并传递一些数据。以下是该过程的工作原理:

在使用密钥UIApplicationLaunchOptionsBluetoothCentralsKey 启动时

  1. application(didFinishLaunchingWithOptions launchOptions) app 使用传递给它的 ID 重新初始化 CBCentralManager。
  2. 然后它会通过常规恢复周期并从 BLE 外设读取数据。
  3. 对云中的服务执行 REST 请求。

假设应用程序在手机重启后至少启动了一次,这几天一切正常(如果应用程序没有运行或被强制内存不足,iOS 会再次正确启动它,假设用户没有手动强制关闭)。

但是,当 BLE 设备有传入请求时,iOS 每隔几天就会停止唤醒应用程序。如果用户重新启动应用程序,几天后一切正常,然后又停止。鉴于我们产品的性质,让我们的应用/外围设备以尽可能可靠的方式协同工作至关重要。

关于它为什么会发生的理论:
(经过仔细检查,所有这些都被解雇了)

  • 用户重启手机后忘记重启应用。
    我们添加了正常运行时间记录,它显示手机在应用启动之间没有重启。

  • 内存警告导致应用程序被启动。
    再次添加日志记录,他们显示没有applicationDidReceiveMemoryWarning

  • 连接不良导致应用程序在上传结果时运行时间超过 10 秒,iOS 将其终止并感到不安
    我们人为地将服务器响应延迟了 15 秒以对此进行测试,并且在测试期间一切都继续正常工作。

关于正在发生的事情以及为什么 iOS 停止通知应用有关传入 BLE 连接的任何想法?

其中一个问题是我们无法弄清楚如何可靠地重现该问题所以任何建议都将不胜感激!

谢谢!


更新 1: 下面是我们如何初始化CBCentralManager

self.centralManager = CBCentralManager(delegate: self, queue: nil, options: [
    CBCentralManagerOptionRestoreIdentifierKey : MyCentralManagerID,
    CBCentralManagerOptionShowPowerAlertKey : 0])

我看到一些建议队列参数不应该为零。鉴于我无法可靠地重现问题,因此在我能够自信地观察其影响之前,我会犹豫是否要进行更改。

【问题讨论】:

    标签: ios iphone bluetooth-lowenergy cbcentralmanager


    【解决方案1】:

    首先我想说的是,我使用 CoreBluetooth 已经有很长时间了,据我所知,CoreBluetooth 状态保存和恢复根本无法可靠地工作。你可以让它“正常”地工作,但除非苹果有一天修复它,否则你永远无法让它可靠地重新连接。

    有很多错误导致它无法正常工作,但我会给你一个我认为会导致你的问题的错误:

    如果事件源自您正在与之通信的外围配件(例如连接/断开连接事件和特征通知),则状态恢复只会因蓝牙相关活动而重新启动您的应用。对于其他事件,最重要的是一般蓝牙状态更改事件,您的应用将不会重新启动并通知此事件。这很糟糕的原因是因为所有蓝牙状态更改事件都会取消所有挂起或当前的连接,这意味着挂起的连接将被丢弃并且您的应用程序不会收到通知。这实际上意味着您的应用程序仍然会认为连接仍然处于未决状态,而实际上它们并非如此。由于此时您的应用程序已终止,它再次唤醒的唯一方法是让用户再次手动启动它(或者为此目的“破解”其他后台模式,这也不是很可靠)。

    如果用户切换飞行模式、切换蓝牙、重启 iOS 设备或任何其他未定义的原因(许多原因会导致状态更改),就会发生这种情况……

    但这只是一个错误。许多其他情况也存在,例如 XPC 连接在不同时间无故中断。我还注意到,挂起的连接可以进入“边缘”模式,其中外围状态设置为正在连接,但实际上它永远不会连接,除非您循环连接状态。

    无论如何,我很难过,但如果您正在开发一个必须依赖在后台重新连接外围设备的应用程序,那么我不建议您这样做。你会感到沮丧。我可能会写一篇关于 Apple 不想修复的 Core Bluetooth 中的所有错误的文章。更奇怪的是,您可以很容易地通过一个应用程序破坏设备上的全局蓝牙连接,因此在设备重新启动之前没有应用程序可以使用蓝牙。这很糟糕,因为它违反了 Apple 自己的沙盒原则。

    【讨论】:

    • Anton,感谢您在此问题上发表如此透彻而深思熟虑的帖子。试图弄清楚这一点非常令人沮丧,而您的回答证实了我们一直担心的问题 - 问题出在 iOS 本身,而不是我们的应用正在做什么,因此在很大程度上超出了我们的控制范围。
    • 我能够在这些问题上获得“一些”可靠性,请在此处查看我的帖子 stackoverflow.com/questions/45738824/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-23
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 1970-01-01
    相关资源
    最近更新 更多