iBeacon区域监控和20个以上信标的距离感应?

13

我一直在开发一个基于iBeacon的iOS原型应用程序,根据办公室员工所在的位置提供与位置相关的信息。理想情况是每当员工进入或离开办公室时,都会触发回调,以通知他们相关信息(可能需要首先进行服务器查询等操作)。我们还希望在应用程序后台运行或终止时也能实现这一点;幸运的是,我们已经知道即使应用程序处于后台或挂起状态,信标区域边界越过也会触发适当的CoreLocation回调。

从我的调研中得知,我有两种方法来处理信标区域监控:

  1. 为每个iBeacon提供自己的CLBeaconRegion,并独立地监视每个这些区域。
  2. 监视对应于多个iBeacon的CLBeaconRegion - 例如,每个iBeacon具有相同的UUID,只监视对应于该UUID的CLBeaconRegion - 然后尝试使用测距法确定哪个信标触发了边界越界。

迄今为止,我选择了第一种方法。这种方法的优点是我可以为每个单独的信标获取didEnterRegion:和didExitRegion:调用,并立即知道我进入/退出的是哪个信标。而且,我只会获取一次进入和一次退出的调用,这正是我想要的。不幸的是,我刚意识到这种方法也限制了我最多只能使用20个信标(因为每个信标都有自己的区域)。

对于第二种方法的具体实现细节,我不是很熟悉,如果我有错误,请纠正我。但是似乎这种方法有更多缺点:

  • 当应用程序处于后台时,Apple不鼓励进行测距,因为结果可能不太准确。
  • 测距调用每秒钟触发一次,而我只想要“进入/退出”回调。
  • 如果信标存在区域重叠,测距调用可能会不断地翻转哪一个信标是“最近的”,这将进一步复杂化事情。

基本上,我想知道是否有一种方法可以利用选项#2,但仍然具有选项#1的优点——只需一个进入或退出回调即可快速轻松地确定哪个信标触发了区域更改?

希望这个问题足够清楚。在我的脑海中并不完全清晰,尤其是测距的工作原理。

3个回答

10

选项#2显然更加复杂,但是你必须接受这些复杂性才能绕过20个区域监控限制。

几点说明:

  • 在后台中,你只有大约5秒的测距时间,这不会给你足够的时间来平均每个信标的RSSI(信号强度)以得到良好的距离估计。因此,是的,估计值将不太准确。如果你理解这个限制并且对于你的用例可以接受它,那么在后台进行测距没有问题。

  • 是的,在进入区域后,你会获得每个信标的多次测距调用,并且你将不会收到任何关于退出区域的回调。你需要编写额外的代码来处理这种情况。我通过维护一个NSMutableArray来完成了这个操作,其中包含所有唯一的信标(相同的UUID / Major / Minor),并在测距回调中更新它。然后你可以在区域退出回调中访问此数组,以便知道哪个信标消失了。当然,可能会在5秒的后台测距时间结束后看到其他信标,但你的应用程序永远不会知道这些信标。对于这个选项,你必须接受这个限制。

  • 虽然在测距时距离估计的误差可能会错误地告诉你哪个信标最近,但是当进行监控时,你甚至会面临更糟糕的问题,因为你根本不会得到距离估计。如果多个信标在同一时间进入监控范围,那么不能保证你收到的第一个进入区域回调就是最近的信标。因此,如果你的用例要求基于最近的信标采取行动,则必须进行测距(知道距离估计可能有误。)


感谢您详细的回复,David!我看到一些例子,人们只在didEnterRegion:上调用startRangingBeaconsInRegion:,并在didExitRegion:中调用stopRangingBeaconsInRegion:。您建议这样做,还是只在开始监视区域时启动扫描信标,并永远不停止扫描? - UberJason
我看不出来保持启动/停止测距的理由。iOS会强制执行在后台无法进行测距(除了进入/退出事件后的五秒),所以保持测距开启并不会给您的应用程序使用任何额外的资源。 - davidgyoung

7
第二种方法的缺点是,检测特定信标的进入将仅基于测距,如果应用程序被杀死,则无法工作。原因是,我们只监视具有特定UID的一个区域,因此我们将仅一次获取didEnterRegion。如果应用程序终止或后台测距停止,则不会再次检测到具有相同UID的下一个信标。
我建议结合上述方法:
- 对所有信标使用相同的UID。 - 使用收集到的major/minor值唯一标识信标。 - 如苹果文档所述,始终通过添加和删除信标来将监视区域的数量保持在20以下(最好在服务器上保留信标邻居关系图)。 - 进入区域时开始测距...并识别major/minor并计算接近度。 - 离开区域时停止测距。 - 从测距方法中查找最接近的信标(需要跳过未知范围信标)。 - 在给定时间内仅监视最接近信标的邻居。
当实现这两个选项时,我们应该考虑一个事实,即iBeacon将在200英尺距离内被检测到。200英尺范围内可能有多个信标。

2
如果您为每个信标使用相同的UUID,您只需要设置主/次要编号以区分不同的信标。这样,您只需监视一个信标而不是20个以上。然后,只需从其他标识符中确定哪个是哪个即可。这就是目前星巴克和其他零售商应用程序的工作原理。全球范围内只有一个信标,并使用不同的标识符在后端进行分类。

1
这是我所描述的第二个选项。但是,您无法通过didEnterRegion:或didExitRegion:以此方式获取信标信息(例如major和minor),因为我正在监视的区域仅配置了UUID。 - UberJason
1
@bill burgess,您好!如何使用单个CLBeaconRegions来识别多个信标的范围? :) - Rushabh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接