iOS Geofence CLCircularRegion监控.locationManager:didExitRegion似乎没有按预期工作

Mon*_*lue 29 core-location cllocationmanager ios geofencing clcircleregion

我目前正试图让我的应用程序监控特定区域使用CoreLocation但是我发现它似乎没有按预期工作,在我看来,它不能用于每个位置的小半径设置,即10米.

我还整理了一个小测试应用程序,在地图上绘制圆形半径,以便我可以直观地看到发生了什么.

我用于监控位置的代码如下:

self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;

// Set-up a region
CLLocationDegrees latitude = 52.64915;
CLLocationDegrees longitude = -1.1506367;
CLLocationCoordinate2D centerCoordinate = CLLocationCoordinate2DMake(latitude, longitude);

CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:centerCoordinate
                                                                 radius:10 // Metres
                                                             identifier:@"testLocation"];

[self.locationManager startMonitoringForRegion:region];
Run Code Online (Sandbox Code Playgroud)

我没有在这里为DidEnter区域等提出代码,因为我知道当我离监控区域超过100米时可以工作.

这是应用程序的屏幕截图,当我距离地图上的紫色位置超过10米时,确实的出口区域事件不会触发,但是如果我将我的位置切换到伦敦则会触发它以及当我设置我的位置时回到目前蓝色位置的地方它也会发射.

示例区域

有没有人知道最小区域半径是否有限制,或者我做错了什么.

谢谢亚伦

nev*_*ing 52

我认为区域监测不会对这么小的半径有效.

  • GPS芯片的最佳精度kCLLocationAccuracyBestForNavigation通常只有10米.
  • Apple表示(在位置和地图PG中)区域的最小距离应假设为200米
  • 我听说区域监控正在使用WiFi来获取它的位置(这对于省电是有意义的).WiFi精度更像是20m-100m.我不确定如何使用其他应用程序使用背景位置(即使用GPS)会影响这一点.也许,位置管理员会共享信息以提高准确性.
  • 区域监控可能需要30秒才能在区域内进行一次点火,并且在离开区域后需要几分钟才能点火(以防止位置故障触发).
  • 当首次引入区域监测时,他们表示只能在100米区域内工作,而任何较小的区域都会被抬高.这可能仍然会发生.
  • 有一种不推荐使用的方法startMonitoringForRegion:desiredAccuracy:,允许您指定区域边界以外的距离以开始生成通知.据推测,这个功能已经进入,startMonitoringForRegion:但仍然存在.一个10米的区域最终可能会有10米的缓冲区.
  • 如果要执行此操作,请在要监视的位置周围指定一个更大的区域,当设备在该区域唤醒时,启动后台位置更新(GPS)并使用CLCircularRegion's -containsCoordinate:在设备手动在10米范围内时触发.该方法由Apple正式批准(参见WWDC 2013 Session 307).

来自CLCircularRegion文档:

请记住,位置管理器在跨越区域边界时不会立即生成通知.相反,它应用时间和距离标准来确保交叉是有意的并且应该真正触发通知.因此,选择适当的中心点和半径,并给您足够的时间提醒用户.

位置和地图PG:

区域事件可能不会在跨越区域边界后立即发生.为防止虚假通知,iOS在满足某些阈值条件之前不会发送区域通知.具体而言,用户的位置必须越过区域边界,远离边界移动最小距离,并在报告通知之前保持在该最小距离至少20秒.
特定阈值距离由当前可用的硬件和定位技术确定.例如,如果禁用Wi-Fi,则区域监控的准确性要低得多.但是,出于测试目的,您可以假设最小距离约为200米.

凯文·麦克马洪(Kevin McMahon)这篇文章中进一步深入了解了这篇文章,他在2012年WWDC实验室向核心位置工程师询问了区域监测情况.此信息在此期间会发生变化,但有关区域类别的部分很有意思.这是一个编辑:

精细区域(0 - 150米)
- 地面100米,此类别的范围实际为100-150米.
- 对于区域而言,此大小的性能在很大程度上取决于与位置相关的硬件
- 核心位置检测并调用适当的委托方法所花费的时间大约是跨越区域边界后的2-3分钟.
- 一些开发人员已经独立地发现,较小的区域会看到更快的回调,并且会聚集较小的区域以覆盖一个大区域以改善区域交叉通知.

  • 该帖子应受到保护。 (2认同)

mem*_*ons 24

这似乎是一个错误CLLocationManager.我已经使用各种区域半径配置进行了大量测试,locationManager:didExitRegion并且没有以预期的方式触发.这似乎是一个相当讨厌的错误或区域监控根本没有像文档建议那样发生.我有任何想要它的人都可以使用测试工具:

http://www.mediafire.com/download/x863zkttltyalk6/LocationTest.zip

在模拟器中运行它并通过在iOS模拟器菜单中选择Debug - > Location - > Freeway Drive来开始测试.您看到的数字是距受监控区域中心的距离.设备位于受监控区域内时背景颜色为绿色,区域外时背景颜色为红色.距离下方的文本是事件日志.

在此输入图像描述

运行该应用程序后,您应该看到locationManager:didExitRegion距离受监控区域5319米的火灾.该路线将每37分钟循环一次,您将看到离开该区域的设备总是在5319米处.

我已经提交了Apple雷达(17064346).一旦我收到他们的回复,我会更新这个答案.至少那时我们会从规范来源获得一些意见.

这是发送给Apple的详细文本:

使用iOS模拟器以及iPhone 5S上的测试应用程序,CLLocationManager似乎不会以预期的方式触发didExitRegion回调.无论被监视的圆形区域的半径如何,在达到约5000米的阈值之前不会发生回调.

重现步骤:
1.运行附加的应用程序
2.通过在iOS模拟器中选择调试 - >位置 - >高速公路驱动器来启动区域跟踪
3.监控应用程序.大#表示距监视区域中心的距离.
在大约190秒和5300米后,退出地点终于开火了.

该问题似乎与该地区的规模无关.根据Apple文档,甚至支持小区域:

在iOS 6中,半径在1到400米之间的区域在iPhone 4S或更高版本的设备上运行得更好.(在iOS 5中,半径在1到150米之间的区域在iPhone 4S和更高版本的设备上运行得更好.)在这些设备上,应用程序可以在3到5分钟内平均接收输入的适当区域或区域退出通知,如果不是更快.

虽然地区事件不会立即发生,但它们应该很快发生.来自Apple文档:

区域事件可能不会在跨越区域边界后立即发生.为防止虚假通知,iOS在满足某些阈值条件之前不会发送区域通知.具体而言,用户的位置必须越过区域边界,远离边界移动最小距离,并在报告通知之前保持在该最小距离至少20秒.

这完全不是我在测试工具中看到的.在模拟器上,在locationManager:didExitRegion事件发生之前,设备将始终距离该区域5000米以上.


Ric*_*cky 16

我喜欢Michael和Nevan的答案.我想从个人经验/意见中添加更多信息,以开发基于位置的iOS应用程序区域监控,并重点介绍一些要点: -

对区域监测要切合实际

区域监控使用全球定位系统(GPS),Wifi和其他技术来确定设备是在监控区域内还是外.不要忘记,我们的地球是510平方公里,约30%是土地(1.49亿平方公里).这是一个巨大的领域.还记得最近的MH370丢失案吗?我们目前最先进的技术甚至无法确定该失踪飞机的估计区域.

如果要监视半径仅为10米的小区域.它可能在一个高密度城市内工作,有很多手机信号塔和无线连接区域.但与此同时,信号可能被高层塔阻挡,这可能导致信号丢失几秒/分钟,从而导致通知延迟.

因此,在决定要监控的区域有多大之前,您必须考虑上述信息.我个人认为10米半径太小了.

在监测区域数量上要切合实际

当前的核心位置技术只能在一个应用程序上监控最多20个区域.确保受监控的区域也不要太靠近.

我亲自测试了3个半径约100米的区域,这些区域彼此相差约200米.有时,当我开车经过时,我可以从所有这3个地区收到通知,但有时候,我只能从第一个地区收到通知.可能是什么原因?我不知道.这些地区可能彼此太靠近.或者手机信号塔决定我的设备实际上并不在受监控区域内.

StackOverFlow上有一个人想监视我们地球上的1800点.不要像他一样,因为他是非常不现实的,可能不理解当前Core Location技术的局限性.链接:检查用户位置是否接近某些点

微调LocationManager

如果您的应用需要监控小区域或需要经常更新位置.以下是您的位置管理器的潜在属性.

self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;
Run Code Online (Sandbox Code Playgroud)

kCLLocationAccuracyBestForNavigation会消耗更多的电池kCLLocationAccuracyBest.但是,它会更准确.

当在不同的受监控区域同时触发多个通知时,我发现iOS 7中的区域监控存在故障.我找到了一个解决这个故障的解决方案.有关详细信息,请访问:iOS 7上的区域监控故障 - 同时发出多个通知

不要过于雄心勃勃

您可能已经使用了一些可以监控小区域的应用程序,并且非常准确,并且能够在您踏入该区域的同一时间通知您.而且你有灵感来开发完全相同的应用程序来与它们竞争.但是你明白幕后发生了什么吗?他们使用了哪些其他技术?和他们合作的合作伙伴是什么?

我对此做了一些研究,发现他们使用的一些技术不公开.其中一些公司资金雄厚,可以向电信公司支付额外费用,以便获得最佳的位置准确性,从而获得最佳用户体验.我不明白它是如何工作的细节.我相信大多数位置确定实际上是在服务器端(后端),而不是移动(前端).

因此,这些公司开发的应用程序不仅可以精确定位最准确的位置,而且不会消耗大量电池.

注意:我只想分享我的2美分.以上信息包括我的经验和个人意见.它可能不是100%准确,因为我仍在学习核心位置区域监控.


nid*_*IOS 6

我同意Michael G. Emmons的观点,并希望分享我的经验:

我用三个区域测试了我的代码,如下图所示:

在此输入图像描述

解释行为:

  • 我当前的位置是Region-1,我开始监控上述三个区域,并调用requestStateForRegion,以确定内部是否有任何区域,我当前站在哪里.
  • 然后我得到"输入"通知,前两个区域(区域1和区域2),但它应该只检测区域-1.
  • 现在当我进入region-2时,我收到了region-3的Enter通知.但我应该在这里获得region-2的通知.
  • 现在,当我再次进入region-1时,我为区域-3触发了Exit事件,并且这仍然继续.
  • 但我没有得到前两个区域的任何进入/退出事件,直到我距离前两个区域至少超过7Km-10Km.

预期行为: - 只有当我越过区域边界或区域内时,才会触发进入/退出事件,而不是在距离该区域500米之前.

我的假设:

  • 在所有实验之后我注意到的是,当我为所有三个区域调用"requestStateForRegion"时,
  • 它检测半径为5000m的区域内的所有区域,这就是为什么它同时检测前两个区域(区域-1创建一个半径为5000m的圆,区域-2在其范围内,这就是为什么区域-2也被检测到) ).
  • 当用户移动距离远超过10Km时,将调用其Exit事件,当用户返回这些区域时,将触发其Enter事件.与上面Aaron Wardle解释的情况相同.
  • 正在检测Region-3,因为当用户进入region-1时,即.距离region-3 8-9km,因此为此事件触发了Exit事件,当用户在区域2的路线上时,即使区域-3距离5000米,仍然会检测到区域-3并且发射,输入region-3的事件.

因此我认为5000米内的所有区域都被检测到,并且当用户从检测到的区域移开10公里时,其Exit事件将被触发.否则如果用户在5Km范围内,它将永远不会再次调用它进入/退出事件.

如果有人解决了这个问题,请更新我,或者Apple在任何地方解决此问题.