本文介绍了CBCentralManager是否超时连接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道答案的名义上是否,但是我的意思是真的-如果应用程序进入后台(启用​​了BTLE后台处理)会怎样? 24小时?在应用程序更新中吗?

I know the answer is nominally "no", but I mean really—what if the app goes into the background (with BTLE background processing enabled)? For 24 hours? Across an app update?

在重新连接到外围设备标题下,此描述了一种重新连接工作流程,该工作流程首先尝试通过以下方法重新连接到以前的已配对的$ P外围设备: / code>,但是如果连接失败,则再次开始扫描。如果没有正式的超时,您如何知道何时放弃 connect -到以前找到的外围设备?如果您想重新连接到先前找到的BTLE设备,而又无需用户与您的应用进行交互,那么您如何知道何时开始/继续扫描呢?

Under the heading "Reconnecting to Peripherals", this Apple documentation describes a reconnection workflow that first tries to reconnect to previously paired peripherals found via retrievePeripheralsWithIdentifiers: but then starts scanning again if you fail to connect. How do you know when to give up on connect-ing to a previously found peripheral if there is no formal timeout? How do you know when to start/keep scanning if the idea is to re-connect to a previously found BTLE device whenever you move back into proximity to it, without the user necessarily interacting with your app?

此外,该页面下方的一条注释还说,某些BTLE设备每次开机时都可能为其自身发明一个随机标识符,因此即使您从 retrievePeripheralsWithIdentifiers:,因为它们的名称已更改,您可能无法连接到它们。在实践中是否有任何BTLE设备这样做?

Also, a note further down that page says that some BTLE devices might invent a random identifier for themselves every time they're powered on, so even though you find some previously paired peripherals from retrievePeripheralsWithIdentifiers: you might not be able to connect to them as their names have changed. Do any BTLE devices do that in practice? That's nuts!

推荐答案

这是一个棘手的问题。 CoreBluetooth框架本身在连接请求上没有官方超时。实际上,它将尝试尽可能长时间地连接外围设备。但是那要持续多久?

This is a tricky one to answer. The CoreBluetooth framework itself does not have an official timeout on connect requests. In fact it will try to connect the peripheral for as long as possible. But how long is that?

不幸的是,这并不是一个很好的定义。您可以完全确定,当应用程序处于前台时,连接不会超时,但是一旦您在后台涉及到连接,事情就不会再变得有趣了。显然,就像您提到的那样,挂起的连接不会在电话重启后保留,等等。这很好,因为没有用户希望该应用在重启后仍然可以运行。关于长期运行的未决连接,您会在Apple的文档中找到它们告诉您选择加入状态保留和恢复,以确保在应用程序暂停并最终终止时正确保留未决的连接。如果按广告说的那样做,那会很好,但不幸的是,它却并非如此。经过多年的研究,我发现在iOS上获得可靠的后台连接几乎是不可能的。我已经报告了有关此主题的许多错误,但到目前为止,尚未解决。

Well, unfortunately this is not something that is very well defined. You can be pretty confident that the connection will not time out while the app is in the foreground, but as soon as you involve connections in the background then things are not so funny any more. Obviously, like you mention, the pending connection will not remain after a phone reboot, etc.. which is fine since no user would expect the app to still be running after a reboot anyway. Regarding long running pending connections, you will find in Apple’s documentation that they tell you to opt-in for State Preservation and Restoration in order to make sure that the pending connections are properly kept while the app is suspended and eventually terminated. This would be good if it worked as advertised, but unfortunately it does not. After many years of working with this I have found that it is nearly impossible to get a reliable background pending connection on iOS. I have reported many bugs on this topic but so far none have been resolved.

我认为您应该特别注意一些问题:

There are a few issues in particular that I think you should pay extra attention to:


    如果您的应用程序处于终止状态时发生蓝牙状态更改事件,则
  1. 状态保留和恢复将完全停止工作。从本质上讲,这意味着如果蓝牙芯片由于任何原因(例如,通过切换蓝牙/飞行模式等)被重置,那么只要外围设备在范围内进行广告宣传,您的应用就不会再由Core Bluetooth重新启动。这样做的原因是,每当重启蓝牙芯片时,您应用程序已设置的所有未决连接都会被清除。问题是您的应用程序将不会重新启动以通知您此更改,因此挂起的连接将永远无法恢复。因此,您的应用程序会认为外围设备可以连接,而实际上它们不会。对我来说,这是最严重的问题,仅此一项就使CoreBluetooth变得极为不可靠。

  1. State Preservation and Restoration will completely stop working if a Bluetooth-state-change event happens while your app is in the terminated state. This essentially means that if the bluetooth chip gets reset for any reason (ex by toggling bluetooth/flight mode/etc..) then your app will never be relaunched again by Core Bluetooth whenever the peripheral is advertising within range. The reason for this is because all pending connections that have been set by your app will be cleared whenever the bluetooth chip is restarted. The problem with this is that your app will not be relaunched to be notified of this change, so the pending connections will never be recovered. So your app will think that the peripherals will connect, while in fact they will not. To me this one is the most serious issue and it alone makes CoreBluetooth extremely unreliable.

有时,框架卡在状态不佳(可能是因为内部竞争条件或类似条件。这可以随机发生,但是您可以通过在didFailToConnect或didDisconnect回调中立即调用connectPeripheral来轻松重现此错误。当发生这种情况时,实际上未设置挂起的连接,则连接状态属性将设置为正在连接。为了避免这种情况,我发现您应该至少等待20毫秒左右再进行连接,例如使用dispatch_after之类的方法。

Sometimes the framework gets "stuck" in a bad state (possibly by an internal race-condition or similar). This can happen randomly, but you can pretty easily reproduce this by calling connectPeripheral immediately in the didFailToConnect or didDisconnect callback. When this happen the "connection state" property is set to "connecting" when a pending connection is in fact not set. To avoid this I have found that you should wait at least around 20ms before connecting, for example using a dispatch_after or something.

该框架内部使用XPC连接进程间通信以传递蓝牙事件。在某些情况下,无论出于何种原因,连接都会中断,连接将会丢失。我不知道为什么会这样,但是无论何时发生,状态保存都会停止,您必须手动重新启动应用程序才能从中恢复。有时我设法在设备sysdiagnose日志中捕获了此信息...

The framework internally uses XPC connections for interprocess communication in order to deliver bluetooth event. On some occasions this will break for whatever reason and the connection will be lost. I don’t know why this happens, but whenever it happens state preservation will stop working and you will manually have to relaunch the app to recover from it. Sometimes I manages to catch this in the device sysdiagnose logs...

使用iPhone 7,同时拥有Apple Watch(已配对手机)如果手表当前未连接(超出范围/飞行模式/电池电量低/或任何其他原因),则将完全断开锁定屏幕后面的所有重新连接。自从最近引入以来,这尤其糟糕!但是,由于某种原因,Apple Watch似乎比其他蓝牙外设具有优先权。

Using an iPhone 7 and at the same time having an Apple Watch (paired the phone) will completely break all reconnects from behind the lock screen in case the Watch is not currently connected (out of range/flight mode/low battery/or any other reason). This is particularly bad since it was introduced recently! But it looks like the Apple Watch for some reason has "priority" over other bluetooth peripherals.

这些来自我的头上,但还有其他问题。关于随机地址,通常这些外围设备使用所谓的随机可解析地址。这意味着它们看起来是随机的,但实际上可以使用通常在初始蓝牙绑定期间共享的IRK(身份解析密钥)来解析它们。据我所知,使用完全随机地址的设备并不是很常见。

These are from the top of my head, but there are other issues as well. Regarding random addresses, most often these peripheral use so called "random resolvable" addresses. This means that they appear random but in fact they can be resolved using an IRK (Identity Resolving Key) which is usually shared during initial bluetooth bonding. Devices that use completely random addresses are to my knowledge not very common.

这篇关于CBCentralManager是否超时连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 23:38