ios CoreBluetooth 应用程序在后台究竟能做什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9896562/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What exactly can CoreBluetooth applications do whilst in the background?
提问by Chris Smowton
The subject says it all, really. Documentation, insofar as it exists at all, suggests that apps written against the CoreBluetooth framework running on iOS devices can add "bluetooth-central" to their background privilege list and so process some kind of Bluetooth events whilst inactive, but which exactevents do and do not get delivered?
这个主题说明了一切,真的。文档,就其存在而言,表明针对在 iOS 设备上运行的 CoreBluetooth 框架编写的应用程序可以将“bluetooth-central”添加到其后台权限列表中,因此在不活动时处理某种蓝牙事件,但哪些确切的事件可以和没有得到交付?
For example:
例如:
- Can I carry on communications with a device I already established a pairing with?
- Can I issue periodic discovery requests to find devices which are out of range / I've never seen before? (For example if I wanted to be able to deliver a notification when a new interesting device is encountered)
- What if a device goes out of range and then comes back? Will I get disconnected and connected events without user intervention, or will I need to be foregrounded and have the user explicitly request reconnection?
- 我可以与已建立配对的设备进行通信吗?
- 我可以发出定期发现请求来查找超出范围/我以前从未见过的设备吗?(例如,如果我希望能够在遇到新的有趣设备时发送通知)
- 如果设备超出范围然后又回来怎么办?我会在没有用户干预的情况下断开连接和连接事件,还是需要前台并让用户明确请求重新连接?
回答by Chris Smowton
Nobody seemed to know, so I bought an iOS developer account and ran some experiments. Here's what I found:
似乎没有人知道,所以我买了一个 iOS 开发者帐户并进行了一些实验。这是我发现的:
When running in the foreground, you can start a scan using CBCentralManager::scanForPeripheralsWithServices. Your scan can be restrictedto devices advertising a particular service, or unrestricted(pass nil for that call's parameter). It can also allowor disallow duplicates; in the former case you'll get a didDiscoverPeripheral callback every time the iPhone receives an advertisment packets; in the latter you'll only get one callback per device found.
在前台运行时,您可以使用 CBCentralManager::scanForPeripheralsWithServices 开始扫描。您的扫描可以仅限于广告特定服务的设备,也可以不受限制(为该调用的参数传递 nil)。它还可以允许或禁止重复;在前一种情况下,每次 iPhone 收到广告数据包时,您都会收到一个 didDiscoverPeripheral 回调;在后者中,每找到一个设备你只会得到一个回调。
When you enter the background, the rules appear to be as follows:
进入后台后,出现的规则如下:
- If you were running an unrestrictedscan, it will be silently cancelled. You will not get any didDiscover callbacks.
- If your scan was restricted(i.e. you specified one or more service UUIDs you were looking for), your scan will continue to run, but the allow duplicates flag will be ignored. This means that you will now only get didDiscoverPeripheral callbacks for newdevices. If all devices were seen whilst in the foreground you will get no callbacks at all.
- Starting and stopping the scan does notreset which devices are considered new. If there is one device present, you will only get a single callback, even across multiple scans, unless...
- If you connectto a device, then disconnect, then scan again, the device will be enumerated again (i.e. you will get one more call to didDiscoverPeripheral). I guess iOS regards that as having "shown interest" in the device.
- 如果您正在运行不受限制的扫描,它将被静默取消。您不会收到任何 didDiscover 回调。
- 如果您的扫描受到限制(即您指定了一个或多个您正在寻找的服务 UUID),您的扫描将继续运行,但允许重复标记将被忽略。这意味着您现在只会获得新设备的didDiscoverPeripheral 回调。如果在前台看到所有设备,您将不会收到任何回调。
- 启动和停止扫描不重置该设备被认为是新的。如果存在一台设备,您只会收到一个回调,即使是多次扫描,除非...
- 如果您连接到一个设备,然后断开连接,然后再次扫描,该设备将再次被枚举(即您将再接到一次对 didDiscoverPeripheral 的调用)。我猜 iOS 认为这是对设备“表现出兴趣”。
I don't know whether connect attempts to nonconnectable devices (e.g. BLE Advertisers, like those implementing the proximity profile) is good enough as my example devices are connectable. However at least for connectable devices, this scan/connect/disconnect/scan procedure suffices to poll for a device's presence in the background.
我不知道尝试连接到不可连接的设备(例如 BLE 广告商,如实现邻近配置文件的那些)是否足够好,因为我的示例设备是可连接的。然而,至少对于可连接的设备,这个扫描/连接/断开/扫描过程足以轮询设备在后台的存在。
The above results were gathered using an iPhone 4S running iOS 5.0.1
以上结果是使用运行 iOS 5.0.1 的 iPhone 4S 收集的
回答by mash
In addition to Chris's answer:
除了克里斯的回答:
- If your app has "bluetooth-central" background mode and is connected to a peripheral, you can receive notifications (
peripheral:didUpdateValueForCharacteristic:error:
) from the peripheral in background, even after 10minutes.
- 如果您的应用程序具有“bluetooth-central”后台模式并连接到外围设备,您可以
peripheral:didUpdateValueForCharacteristic:error:
在后台接收来自外围设备的通知 ( ),即使在 10 分钟后。
So when you want to continuously run in background you have 2 options:
因此,当您想在后台持续运行时,您有两个选择:
- Run the "connect, disconnect, scan again" loop
- Make the peripheral send notifications
- 运行“连接、断开、再次扫描”循环
- 使外围设备发送通知
Later should be the "Event backgrounding" from WWDC 2012 Core Bluetooth videos https://developer.apple.com/videos/wwdc/2012/But the former looks like a hack, I don't want to rely on it.
后来应该是WWDC 2012 Core Bluetooth 视频中的“事件背景” https://developer.apple.com/videos/wwdc/2012/但前者看起来像一个hack,我不想依赖它。
I tested this on iPhone5, iOS6.1.4
我在 iPhone5、iOS6.1.4 上测试过
Apple finally released the Core Bluetooth Programming Guideand here's the official note about
苹果终于发布了核心蓝牙编程指南,这里是官方说明
回答by user108
It is also good to note the behavior of backgrounding and CoreBluetooth related to the iBeacons, although Apple likes to think of this as a CoreLocation functionality:
还需要注意与 iBeacons 相关的背景和 CoreBluetooth 的行为,尽管 Apple 喜欢将其视为 CoreLocation 功能:
When notifications for an iBeacon region are turned on, they will notify the user of region entry or exit. These notifications can be made to depend on whether the display is on or off. These notifications will work even when the app requesting notifications is in the background. (This much is clear in the documentation).
Not so obvious: If you use the iBeacon ranging API, then your app has to be in the foreground. It does not explicitly say this in the documentation-- in fact, one can be mislead to think that ranging should work in the background from the documentation. However, an Apple engineer clarifies this in a post buried somewhere in a long thread on the Apple developer forum, and I've seen this fail too. Ranging will work only in the foreground.
One can discover other services being advertised by a peripheral advertising iBeacons. But this will work only in the foreground. So if you want the central to be notified of proximity using iBeacons, and then do some other transactions using other BLE-based services, this will work, but only in the foreground. It will not work in the background. For transactions with BLE-based services in the background, the advertisement has to be a regular BLE advertisement, not an iBeacon. You cannot use an iBeacon advertisement to help the discovery process in the background, and then switch to using BLE-services in the background. (I would have very much liked this to work, but no dice).
当 iBeacon 区域的通知打开时,它们会通知用户区域进入或退出。可以根据显示器是打开还是关闭来发出这些通知。即使请求通知的应用程序在后台,这些通知也能正常工作。(这在文档中很清楚)。
不太明显:如果您使用 iBeacon 测距 API,那么您的应用程序必须处于前台。它没有在文档中明确说明这一点——事实上,人们可能会误以为测距应该在文档的背景中工作。然而,一位 Apple 工程师在 Apple 开发者论坛的一个长帖子中的一篇帖子中澄清了这一点,我也看到过这种失败。测距只能在前台工作。
可以发现外设广告 iBeacons 正在广告的其他服务。但这只能在前台工作。因此,如果您希望使用 iBeacons 通知中央接近度,然后使用其他基于 BLE 的服务进行一些其他事务,这将起作用,但仅限于前台。它不会在后台工作。对于后台基于 BLE 的服务的交易,广告必须是常规的 BLE 广告,而不是 iBeacon。您不能在后台使用 iBeacon 广告来帮助发现过程,然后在后台切换到使用 BLE 服务。(我非常喜欢这个工作,但没有骰子)。
回答by Igor Vlasov
I've just learnt background mode for BLE devices on iOS8.3 & 8.4 and have found some differences from above:
我刚刚在 iOS8.3 和 8.4 上学习了 BLE 设备的后台模式,并发现了与上面的一些不同之处:
if I start
[centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:kServiceUUID]] options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @YES }];
如果我开始
[centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:kServiceUUID]] options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @YES }];
from
从
- (void)applicationDidEnterBackground:(UIApplication *)application
I found enumeration returns the same device every call with different RSSI, so CBCentralManagerScanOptionAllowDuplicatesKey isn't ignored.
我发现枚举每次使用不同的 RSSI 调用都会返回相同的设备,因此不会忽略 CBCentralManagerScanOptionAllowDuplicatesKey。
- If app is in foreground it discovered BLE device 50 times in sec. If app is in background but the phone screen is active app discovered BLE devices 6times in sec. If phone screen is blocked app discovered BLE devices 1time in sec.
- 如果应用程序在前台,它会在 1 秒内发现 BLE 设备 50 次。如果应用程序在后台但手机屏幕处于活动状态,应用程序会在 1 秒内发现 6 次 BLE 设备。如果手机屏幕被阻止,应用程序会在 1 秒内发现 BLE 设备。