iOS 在从外设传入 BLE 连接时停止唤醒应用程序

2024-02-18

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

使用密钥启动后UIApplicationLaunchOptionsBluetoothCentralsKey in

  1. application(didFinishLaunchingWithOptions launchOptions)应用程序使用传递给它的 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])

我看到一些建议,队列参数不应为零。鉴于我无法可靠地重现问题,我会犹豫是否要进行更改,直到我可以自信地观察其效果。


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

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

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

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS 在从外设传入 BLE 连接时停止唤醒应用程序 的相关文章

  • 如何使用 Swift 循环 Array> [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 给我一个 循环遍历 的例子和解释array
  • 如何打开/关闭 iPhone 相机闪光灯 swift 2?

    我正在寻找如何打开 关闭 iPhone 的相机闪光灯 我发现了这个 IBAction func didTouchFlashButton sender AnyObject let avDevice AVCaptureDevice defaul
  • iOS 7 UITableView:这是一个错误还是我的问题?

    请参阅附图 在 iOS 7 的表格视图中 UIKit 在附件视图和重新排序控件之间绘制一条细灰色垂直线 但是 当滚动表视图时 某些单元格中不会绘制这条线 附图中的单元格 1 2 和 8 中不存在该值 为什么是这样 我该如何修复它 我在 ip
  • 4.4 中新的 Objective-c 文字

    我可以写 42 这会创建一个NSNumber with int值 42 我可以用变量来做到这一点 例如 someIntVar 显然我尝试过但它不起作用 这很糟糕 因为然后我必须经历 NSNumber numberWithInt someIn
  • 苹果的外部配件(蓝牙)仅适用于 MFI 设备? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我的学士论文的目标是通过蓝牙适配器将光串行设备连接到 iPad 目前我正在努力应对苹果的限制 我经常在网上看到我可以使用支持的配置文件 h
  • 如何在iOS8自定义键盘上方添加工具栏?

    My problem is write picture I really need you help Maybe inputAccessoryView inputAccessoryViwController can be used but
  • 如何在 Swift 中退出“DispatchQueue.main.asyncAfter”

    我想在调用 deinit 时退出 DispatchQueue main asyncAfter 子视图 swift DispatchQueue main asyncAfter deadline now 5 0 self doSomething
  • 数组索引超出范围的表视图

    我正在使用数组从数据库读取数据 目前数组中有 8 个项目 我正在尝试制作一个有节标题的表格 目前我有 4 个部分 并且我已正确设置并且它有效 它也可以在第一次运行时运行 但是当我尝试向后滚动时 我发现索引超出了范围 我正在使用 myarra
  • 使用 CLPlacemark、administrativeArea、iOS6/iOS7 更改内容

    我计划为 ios 7 制作一个应用程序 并且有管理区域地标属性的问题 对于 iOS6 我得到行政区域的全名 例如 加利福尼亚 但对于 iOS7 我得到 CA 的值 当情况如此变化时 这是一个问题 有什么方法可以控制这个输入 使其更加一致吗
  • 新的 iTunes 连接界面错误“您必须选择一个版本”

    当尝试将我的新应用程序提交到应用程序商店时 我注意到苹果已经更改了其网站界面 更新元数据和关键字并点击 提交审核 后 我收到错误 您必须选择一个版本 通过谷歌搜索 我没有找到答案 但是 我注意到 构建 标题旁边有一个加号按钮 您必须在其中选
  • Modal UIViewController 在 iPad 上总是全屏显示。为什么?

    我试图在 iPad 上创建一个简单的模式对话框 无论是小设置 UIModalPresentationFormSheet 还是大设置 UIModalPresentationPageSheet 但无论我做什么 它们都会全屏显示 带有标题栏 模态
  • Eddystone Beacon 中广播的 MAC ID 会改变吗?

    我将描述我的设置 我制作了一个模拟 Eddystone 信标的 Android 应用程序 我能够使用 PlayStore 中的 Beacon Toy 应用程序检测手机上的 Eddystone 信标 但问题是 自上次检查以来 显示的 MAC
  • iOS 上的三字母国家代码

    我知道您可以在 iOS 上获取所有国家 地区的两个字母的国家 地区代码 但是有没有办法获得三个字母的国家代码 So from http en wikipedia org wiki ISO 3166 1 alpha 2 http en wik
  • 从钥匙串保存和加载 |斯威夫特[重复]

    这个问题在这里已经有答案了 如何简单地将字符串存储在钥匙串中并在需要时加载 有几种SO解决方案 主要参考Git repo 但我需要最新 Swift 上最小和最简单的解决方案 当然 我不想添加 git 框架来简单地在我的项目中存储密码 有类似
  • iOS 9.3 出现新的 UIPDFPageRenderOperation 错误?

    我正在向 UIWebView 添加一些 PDF 链接 每次加载并做出滚动手势时 都会收到此错误 objc 910 UIPDFPageRenderOperation 对象 0x14acaca10 过度释放 当已经解除分配时 打断 objc o
  • 以编程方式进行排序时检索 ViewController 堆栈

    static func showMenuView parentVC UIViewController let storyboard UIStoryboard name Main bundle nil let resultController
  • 快速从 appDelegate 中 popToRootViewController

    我试图从应用程序委托弹出到导航堆栈的根视图控制器 并且在将 obj c 中的内容转换为 swift 时遇到一些问题 obj c 中的工作原理 UINavigationController navigationController UINav
  • UIView 子类中使用的 CAShapeLayer 不起作用

    我尝试了几个小时 用 CAShapeLayer 在 UIView 周围获得虚线边框 但我没有显示它 ScaleOverlay h import
  • Base64Transcoder.m 重复符号

    我想使用 SKPSMTPMessage 库 唯一的问题是这个库包含文件 Base64Transcoder m 由于我有 Dropbox SDK 该文件会出现重复错误 我该如何解决这个错误 我不能直接删除 Base64Transcoder m
  • 如何使用 UISlider 以及如何将滑块设置为特定值?

    我是第一次使用 UIslider 首先我想知道如果值的范围是 0 到 10 如何获取滑块位置的值 其次 我希望我的滑块设置为 5 个不同的值 如 1 2 3 4 5 slider should not set between the lab

随机推荐