iOS Geofence CLCircularRegion 监控。locationManager:didExitRegion 似乎没有按预期工作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23866097/
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
iOS Geofence CLCircularRegion monitoring. locationManager:didExitRegion does not seem to work as expected
提问by MonkeyBlue
I am currently trying to get my app to monitor particular regions using CoreLocation
however I am finding that it does not seem to work as expected, it seems to me that it cannot work with small a small radius set for each location i.e. 10m.
我目前正在尝试让我的应用程序使用来监视特定区域,CoreLocation
但是我发现它似乎没有按预期工作,在我看来,它无法在为每个位置设置的小半径(即 10m)下工作。
I've also put together a little test app which plots the circle radiuson a map so I can visually see what is happening.
我还制作了一个小测试应用程序,它在地图上绘制圆半径,以便我可以直观地看到发生了什么。
The code I am using for monitoring locations is as follows:
我用于监控位置的代码如下:
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];
I have not put up the code here for DidEnter
region etc as I know that works when I go over 100m away from the monitored region.
我还没有在此处为DidEnter
区域等放置代码,因为我知道当我离开监控区域超过 100m 时会起作用。
Here is a screen shot of the app when I am well over 10 meters away from the purple location on the map, the did exit region events do not fire, however if I switch my locationto Londonit fires and also when I set my locationback to where the blue location is currently it also fires.
这是应用程序的屏幕截图,当我距离地图上的紫色位置超过 10 米时,确实退出区域事件不会触发,但是如果我将我的位置切换到伦敦它会触发,并且当我设置我的位置时回到蓝色位置当前的位置,它也会触发。
Does anyone know if there is a limitation with the minimum region radius at all or perhaps I am doing something wrong.
有谁知道最小区域半径是否有限制,或者我做错了什么。
Thanks Aaron
谢谢亚伦
回答by nevan king
I don't think region monitoring will work well for such a small radius.
我认为区域监控对于这么小的半径来说效果不佳。
- The best accuracy with the GPS chip and
kCLLocationAccuracyBestForNavigation
is often just 10 meters. - Apple says (in the Location & Maps PG) that the minimum distance for regions should be assumed to be 200m
- I've heard that region monitoring is using WiFi to get it's position (which makes sense for power savings). WiFi accuracy is more like 20m-100m. I'm not sure how having another app using background location (i.e. using GPS) would affect this. Probably, the location manager would share information to make the accuracy better.
- Region monitoring can take 30 seconds to fire once inside a region, and a couple of minutes to fire after leaving a region (to prevent location glitches from triggering it).
- When region-monitoring was first introduced, they said that it would only work with 100m regions and anything smaller would be bumped up. This probably still happens.
- There's a deprecated method
startMonitoringForRegion:desiredAccuracy:
which allowed you to specify the distance past the region border to start generating notifications. Presumably this feature has been rolled intostartMonitoringForRegion:
but is still there. A 10m region might end up with a 10m buffer. - If you want to do this, specify a larger region around where you want to monitor, and when the device wakes up in that region, start background location updates (GPS) and use
CLCircularRegion
's-containsCoordinate:
to trigger when the device is within 10m manually. This method is officially sanctioned by Apple (see WWDC 2013Session 307).
- GPS 芯片的最佳精度
kCLLocationAccuracyBestForNavigation
通常只有 10 米。 - Apple 表示(在Location & Maps PG 中)区域的最小距离应假定为 200m
- 我听说区域监控正在使用 WiFi 来获取它的位置(这对节能很有意义)。WiFi精度更像是20m-100m。我不确定让另一个应用程序使用后台位置(即使用 GPS)会如何影响这一点。可能,位置管理器会共享信息以提高准确性。
- 区域监控可能需要 30 秒才能在区域内触发一次,离开区域后可能需要几分钟才能触发(以防止位置故障触发它)。
- 首次引入区域监控时,他们说它只适用于 1 亿个区域,任何更小的区域都会被提升。这可能仍然发生。
- 有一种不推荐使用的方法
startMonitoringForRegion:desiredAccuracy:
,它允许您指定区域边界后的距离以开始生成通知。据推测,此功能已被引入startMonitoringForRegion:
但仍然存在。一个 10m 的区域可能最终会有一个 10m 的缓冲区。 - 如果要执行此操作,请在要监视的位置周围指定一个更大的区域,当设备在该区域唤醒时,启动后台位置更新 (GPS) 并使用
CLCircularRegion
's-containsCoordinate:
在设备在 10m 内时手动触发。这种方法得到了 Apple 的正式认可(参见WWDC 2013Session 307)。
From the CLCircularRegion
docs:
从CLCircularRegion
文档:
Remember that the location manager does not generate notifications immediately upon crossing a region boundary. Instead, it applies time and distance criteria to ensure that the crossing was intended and should genuinely trigger a notification. So choose a center point and radius that are appropriate and give you enough time to alert the user.
请记住,位置管理器不会在跨越区域边界时立即生成通知。相反,它应用时间和距离标准来确保穿越是有意的并且应该真正触发通知。所以选择一个合适的中心点和半径,给你足够的时间来提醒用户。
From the Location & Maps PG:
从位置和地图 PG:
Region events may not happen immediately after a region boundary is crossed. To prevent spurious notifications, iOS doesn't deliver region notifications until certain threshold conditions are met. Specifically, the user's location must cross the region boundary, move away from the boundary by a minimum distance, and remain at that minimum distance for at least 20 seconds before the notifications are reported.
The specific threshold distances are determined by the hardware and the location technologies that are currently available. For example, if Wi-Fi is disabled, region monitoring is significantly less accurate. However, for testing purposes, you can assume that the minimum distance is approximately 200 meters.
跨越区域边界后,区域事件可能不会立即发生。为了防止虚假通知,iOS 在满足特定阈值条件之前不会发送区域通知。具体来说,用户的位置必须越过区域边界,离开边界最小距离,并在通知上报之前保持在该最小距离上至少 20 秒。
具体的阈值距离由硬件和当前可用的定位技术决定。例如,如果禁用 Wi-Fi,区域监控的准确度就会大大降低。但是,出于测试目的,您可以假设最小距离约为 200 米。
There's further inside scoop from this post by Kevin McMahon, who asked the Core Location engineers about region monitoring at a lab at WWDC 2012. This info will have changed in the meantime, but the part about region categories is interesting. Here's an edit:
Kevin McMahon 的这篇文章有更深入的内幕消息,他在 2012 年 WWDC 的实验室向核心位置工程师询问了区域监控。此信息将在此期间发生变化,但有关区域类别的部分很有趣。这是一个编辑:
Fine Region (0 - 150m)
- With the floor of 100m this category's range is effectively 100-150m.
- For regions this size performance is heavily dependent on the location-related hardware
- The amount of time that it takes Core Location to detect and call the appropriate delegate method is roughly 2-3 minutes on average after the region boundary has been crossed.
- Some developers have figured out independently that smaller regions would see quicker callbacks and would cluster smaller regions to cover one large area to improve region crossing notifications.
精细区域 (0 - 150m)
- 以 100m 为底,此类别的范围有效地为 100-150m。
- 对于区域,这种大小的性能在很大程度上取决于与位置相关的硬件
- 在跨越区域边界后,Core Location 检测和调用适当的委托方法所需的时间平均大约为 2-3 分钟。
- 一些开发者独立发现,较小的区域会看到更快的回调,并将较小的区域聚集以覆盖一个大区域以改进区域交叉通知。
回答by memmons
This seems to be a bug in CLLocationManager
. I've done extensive testing using various region radius configurations and locationManager:didExitRegion
does not fire in an expected way. This seems to be either a rather nasty bug or region monitoring does not happen at all like the documentation suggests. I have the test harness available to anyone who wants it:
这似乎是CLLocationManager
. 我已经使用各种区域半径配置进行了广泛的测试,locationManager:didExitRegion
并且没有以预期的方式触发。这似乎是一个相当讨厌的错误,或者像文档所建议的那样,区域监控根本没有发生。我有任何想要它的人都可以使用测试工具:
http://www.mediafire.com/download/x863zkttltyalk6/LocationTest.zip
http://www.mediafire.com/download/x863zkttltyalk6/LocationTest.zip
Run it in the simulator and start the test by by selecting Debug -> Location -> Freeway Drive in the iOS simulator menu. The number you see is the distance from the center of the monitored region. The background color will be green while the device is within the monitored region and red when outside the region. The text below the distance are event logs.
在模拟器中运行它并通过在 iOS 模拟器菜单中选择 Debug -> Location -> Freeway Drive 开始测试。您看到的数字是距监控区域中心的距离。设备在监控区域内时背景颜色为绿色,区域外时为红色。距离下方的文本是事件日志。
After running the app, you should see locationManager:didExitRegion
fire at 5319 meters from the monitored region. The route will loop every 37 minutes and you'll see the device exiting the region always at 5319 meters.
运行该应用程序后,您应该会locationManager:didExitRegion
在距离监控区域 5319 米处看到火灾。该路线将每 37 分钟循环一次,您会看到设备始终在 5319 米处离开该区域。
I've submitted a radar with Apple (17064346). I'll update this answer once I hear back from them. At least then we'll have some input from the canonical source.
我已经向Apple (17064346)提交了一个雷达。一旦我收到他们的回复,我会更新这个答案。至少到那时我们会有一些来自规范来源的输入。
Here's the detailed text sent to Apple:
这是发送给Apple的详细文本:
Using a test app on the iOS simulator as well as on an iPhone 5S the CLLocationManager doesn't seem to fire didExitRegion callbacks in an expected way. Regardless of the radius of the circular region being monitored, the callback won't happen until a threshold of around 5000 meters is hit.
Steps to Reproduce:
1. Run the attached app
2. Start region tracking by selecting Debug -> Location -> Freeway Drive in the iOS simulator
3. Monitor the app. The large # indicates the distance from the center of the watched region.
4. After about 190 seconds and 5300 meters didExitRegion will finally fire.
在 iOS 模拟器和 iPhone 5S 上使用测试应用程序,CLLocationManager 似乎没有以预期的方式触发 didExitRegion 回调。无论被监控的圆形区域的半径如何,在达到大约 5000 米的阈值之前,回调都不会发生。
重现步骤:
1. 运行附加的应用程序
2. 通过在 iOS 模拟器中选择 Debug -> Location -> Freeway Drive 开始区域跟踪
3. 监控应用程序。大 # 表示距观察区域中心的距离。
4. 大约 190 秒和 5300 米后 didExitRegion 最终会开火。
Ths issue does not seem to be related at all to the size of the region. According to the Apple docs, even small regions are supported:
这个问题似乎与该地区的大小完全无关。根据Apple 文档,甚至支持小区域:
In iOS 6, regions with a radius between 1 and 400 meters work better on iPhone 4S or later devices. (In iOS 5, regions with a radius between 1 and 150 meters work better on iPhone 4S and later devices.) On these devices, an app can expect to receive the appropriate region entered or region exited notification within 3 to 5 minutes on average, if not sooner.
在 iOS 6 中,半径在 1 到 400 米之间的区域在 iPhone 4S 或更高版本的设备上效果更好。(在 iOS 5 中,半径在 1 到 150 米之间的区域在 iPhone 4S 及更高版本的设备上效果更好。)在这些设备上,应用程序可以期望在平均 3 到 5 分钟内收到适当的区域进入或区域退出通知,如果不早点。
Although region events don't happen instantaneously, they should happen fairly quickly. From the Apple docs:
尽管区域事件不会立即发生,但它们应该会很快发生。来自苹果文档:
Region events may not happen immediately after a region boundary is crossed. To prevent spurious notifications, iOS doesn't deliver region notifications until certain threshold conditions are met. Specifically, the user's location must cross the region boundary, move away from the boundary by a minimum distance, and remain at that minimum distance for at least 20 seconds before the notifications are reported.
跨越区域边界后,区域事件可能不会立即发生。为了防止虚假通知,iOS 在满足特定阈值条件之前不会发送区域通知。具体来说,用户的位置必须越过区域边界,离开边界最小距离,并在通知上报之前保持在该最小距离上至少 20 秒。
This is not at all what I am seeing in the test harness. On the simulator the device will always be 5000+ meters away from the region before a locationManager:didExitRegion
event occurs.
这根本不是我在测试工具中看到的。在模拟器上,在locationManager:didExitRegion
事件发生之前,设备将始终距离该区域 5000 米以上。
回答by Ricky
I like the answers by both Michael and Nevan. I would like to add more information from my personal experience/opinion in developing Location Based iOS Applicationwith Region Monitoringand also highlight some important points:-
我喜欢迈克尔和内文的答案。我想根据我在开发带有区域监控的基于位置的 iOS 应用程序的个人经验/意见中添加更多信息,并强调一些要点:-
Be realistic on Region Monitoring
在区域监控上实事求是
Region Monitoring is using Global Positioning System (GPS), Wifi and other technologies to determine if the device is inside or outside the monitored region. Don't forget that our earth is 510 square kilometers and about 30% are land (149 million km2). It is a huge area. Remember the recent MH370 missing case? Our current most advance technology could not even pinpoint an estimated region of that missing plane.
区域监控使用全球定位系统 (GPS)、Wifi 和其他技术来确定设备是在监控区域内还是在监控区域外。不要忘记,我们的地球有 510 平方公里,其中大约 30% 是陆地(1.49 亿平方公里)。这是一个巨大的区域。还记得最近的 MH370 失踪案吗?我们目前最先进的技术甚至无法确定那架失踪飞机的估计区域。
If you want to monitor for a small region with only 10 meter radius. It could possibly work inside a highly dense city with a lot of cell towers and wifi connected areas. But at the same time, the signal might be blocked by high rise towers which might cause the signal loss for a few seconds/minutes which caused the delay in delivering the notification.
如果您想监控半径只有10 米的小区域。它可能在一个拥有大量蜂窝塔和 wifi 连接区域的高密度城市中工作。但与此同时,信号可能会被高耸的塔楼阻挡,这可能会导致信号丢失几秒钟/几分钟,从而导致延迟传递通知。
So, you really have to consider the above information before deciding how big is the region that you want to monitor. Personally I think 10 meter radius is too small.
因此,在决定要监视的区域有多大之前,您确实必须考虑上述信息。我个人认为10米半径太小了。
Be Realistic on the Number of Monitored Regions
在监控区域的数量上要切合实际
The current Core Location technology can only monitors up to maximum 20 regionson a single app. Make sure that the monitored regions are not too close to each other as well.
当前的 Core Location 技术最多只能在单个应用程序上监控20 个区域。确保监控区域彼此之间也不会太近。
I personally have tested 3 regions that are about 100 meters in radius which are about 200 meters aways from each others. Sometimes I can get notifications from all these 3 regions when I am driving through them, but sometimes, I can only get the notification from the First region only. What could be the reason? I could not know. The regions might be too close to each other. Or the cell towers decide that my device does not actually inside the monitored region.
我个人测试了半径约 100 米,彼此相距约 200 米的 3 个区域。有时,当我开车经过这 3 个区域时,我可以收到所有这 3 个区域的通知,但有时,我只能收到来自第一个区域的通知。可能是什么原因?我不知道。这些区域可能彼此太靠近。或者手机信号塔决定我的设备实际上不在监控区域内。
There was one person on StackOverFlow who wants to monitor 1800 points on our Earth. Don't be like him as he is quite unrealistic and probably does not understand the limitation of current Core Location
technology. Link: Check if the user location is near of some points
StackOverFlow 上有一个人想要监控我们地球上的 1800 个点。不要像他一样,因为他很不切实际,可能不了解当前Core Location
技术的局限性。链接:检查用户位置是否靠近某些点
Fine Tune The LocationManager
微调 LocationManager
If your app needs to monitor a small area or needs the location update frequently. Here are the potential properties of your location Manager.
如果您的应用需要监控小区域或需要频繁更新位置。以下是您的位置管理器的潜在属性。
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;
kCLLocationAccuracyBestForNavigation
will consume more battery compare with kCLLocationAccuracyBest
. But, it will be more accurate.
kCLLocationAccuracyBestForNavigation
与 相比会消耗更多电池kCLLocationAccuracyBest
。但是,它会更准确。
I found a glitch in region monitoring in iOS 7when there are multiple notifications triggered at the same time in different monitored regions. I have found a solution to filter out this glitch. For more info, please visit: Region Monitoring Glitch on iOS 7 - Multiple Notifications at the same time
我在 iOS 7 的区域监控中发现了一个小故障,当在不同的监控区域同时触发多个通知时。我找到了一个解决方案来过滤掉这个故障。有关更多信息,请访问:iOS 7 上的区域监控故障 - 同时发送多个通知
Don't Be Over Ambitious
不要过于雄心勃勃
You might have used some apps which can monitor a small region and are very accurate and able to notify your the same second you step into the region. And you have the inspiration to develop the exact same app to compete with them. But do you understand what happens behind scene? What additional technologies that they are using? And what partners that they are collaborating with?
您可能使用过一些应用程序,它们可以监控一个小区域并且非常准确,并且能够在您进入该区域的同一秒通知您。你有灵感开发完全相同的应用程序来与他们竞争。但是你了解幕后发生的事情吗?他们正在使用哪些附加技术?他们正在与哪些合作伙伴合作?
I have done some research on that and found out that some of the technologies that they use are not available publicly. Some of those companies are heavily funded and could pay a premium to the telecommunication companies in order to get the best location accuracy for the best user experience. I do not understand the details on how it works. I believe most of the location determination is actually on the server end (back end), not the mobile (front end).
我对此做了一些研究,发现他们使用的一些技术是不公开的。其中一些公司资金雄厚,可能会向电信公司支付溢价,以获得最佳位置准确性,从而获得最佳用户体验。我不明白它是如何工作的细节。我相信大部分位置确定实际上是在服务器端(后端),而不是移动端(前端)。
So, the apps that are developed by those companies not only can pinpoint the best accurate location but also does not consume a lot of battery.
因此,这些公司开发的应用程序不仅可以确定最佳准确位置,而且不会消耗大量电池。
NOTE: I just want to share my 2 cents. The above information consists of my experience and personal opinion. It might not be 100% accurate as I am still learning Core Locationand Region Monitoring.
注意:我只想分享我的 2 美分。以上信息包括我的经验和个人意见。它可能不是 100% 准确,因为我仍在学习核心位置和区域监控。
回答by nidIOS
I do agree with Michael G. Emmons, and want to share my experience too:
我同意Michael G. Emmons 的观点,也想分享我的经验:
I tested my code with three regions as shown in the image below:
我用三个区域测试了我的代码,如下图所示:
Explaining the behaviour:
解释行为:
- My current location is Region-1, and i start monitoring for the above three regions, and call to requestStateForRegion, to determine, if there is any region inside, where i am currenly standing.
- Then i get "Enter" notifications, for first two region (region-1, and region 2), but it should only detect the region-1.
- Now when i enter in region-2, i get the Enter notification for region-3. but i should get the notification for region-2 here.
- Now when i enter in region-1 again, i get the Exit event fired for the region-3, and this continues.
- but i don't get any Enter/Exit events for first two regions, until i move at-least more than 7Km-10Km far from first two regions.
- 我现在所在的位置是Region-1,我开始监控以上三个区域,并调用requestStateForRegion,判断里面是否有我当前所在的区域。
- 然后我收到前两个区域(区域 1 和区域 2)的“输入”通知,但它应该只检测区域 1。
- 现在,当我进入区域 2 时,我会收到区域 3 的进入通知。但我应该在这里收到 region-2 的通知。
- 现在,当我再次进入区域 1 时,我会为区域 3 触发退出事件,并且这种情况仍在继续。
- 但我没有收到前两个区域的任何进入/退出事件,直到我从前两个区域移动至少超过 7 公里到 10 公里。
Expected Behaviour:- Enter/Exit event should be triggered only when i am crossing the boundary of regions, or inside the regions, not before 500 meter from the region.
预期行为:- 只有当我越过区域边界或区域内时,才应触发进入/退出事件,而不是在距区域 500 米之前。
My Assumption:
我的假设:
- What i have noticed after all the experiment, that when i call "requestStateForRegion" for all three regions,
- it detects all regions inside region of radius 5000m, thats why it detects first two regions at the same time (region-1 create a circle of 5000m radius, and region-2 comes in its range, thats why region -2 is also getting detected).
- and when user moves far more than 10Km, their Exit events will be called and when user comes back in these regions, their Enter event will be fired. Its the same case as explained by Aaron Wardleabove.
- Region-3 is getting detected, because,when user enters in region-1, ie. 8-9km far from the region-3, so Exit event is fired for this, and when user is on the route for region-2, here even when region-3 is 5000 meters far, still it detects the region-3 and fire, Enter event for region-3.
- 在所有实验之后我注意到,当我为所有三个区域调用“requestStateForRegion”时,
- 它检测半径 5000m 区域内的所有区域,这就是它同时检测前两个区域的原因(区域 1 创建一个半径为 5000m 的圆,区域 2 在其范围内,这就是区域 -2 也被检测到的原因)。
- 当用户移动超过 10Km 时,他们的 Exit 事件将被调用,当用户返回这些区域时,他们的 Enter 事件将被触发。它与上面Aaron Wardle解释的情况相同。
- 区域 3 被检测到,因为当用户进入区域 1 时,即。距离区域 3 8-9 公里,因此触发退出事件,当用户在区域 2 的路线上时,即使区域 3 距离 5000 米,它仍然检测区域 3 并触发, 输入区域 3 的事件。
So i think that all the regions inside 5000 meters are being detected, and as user moves away 10 km from detected region, its Exit event will be fired. otherwise if user is inside the 5Km range, it will never call it Enter/Exit events again.
所以我认为 5000 米以内的所有区域都被检测到,当用户离开检测区域 10 公里时,它的 Exit 事件将被触发。否则,如果用户在 5Km 范围内,它将永远不会再调用它进入/退出事件。
Please update me on, if anyone has fixed this issue, or Apple documents anywhere about this issue.
请更新我,如果有人解决了这个问题,或者 Apple 文档中关于这个问题的任何地方。
回答by Honey
This is more like an important comment. From Region Monitoring and iBeacon
这更像是一个重要的评论。来自区域监控和 iBeacon
Testing an iOS App's Region Monitoring Support
测试 iOS 应用的区域监控支持
When testing your region monitoring code in iOS Simulator or on a device, realize that region events may not happen immediately after a region boundary is crossed. To prevent spurious notifications, iOS doesn't deliver region notifications until certain threshold conditions are met. Specifically, the user's location must cross the region boundary, move away from the boundary by a minimum distance, and remain at that minimum distance for at least 20 seconds before the notifications are reported.
The specific threshold distances are determined by the hardware and the location technologies that are currently available. For example, if Wi-Fi is disabled, region monitoring is significantly less accurate. However, for testing purposes, you can assume that the minimum distance is approximately 200 meters.
在 iOS 模拟器或设备上测试区域监控代码时,要意识到区域事件可能不会在跨越区域边界后立即发生。为了防止虚假通知,iOS 在满足特定阈值条件之前不会发送区域通知。具体来说,用户的位置必须越过区域边界,离开边界最小距离,并在通知上报之前保持在该最小距离上至少 20 秒。
具体的阈值距离由硬件和当前可用的定位技术决定。例如,如果禁用 Wi-Fi,区域监控的准确度就会大大降低。但是,出于测试目的,您可以假设 最小距离约为 200 米。
回答by Rivera
Soundslike even 1 meter should work (and work better on iPhone 4S+ devices):
听起来甚至 1 米都应该工作(并且在 iPhone 4S+ 设备上工作得更好):
startMonitoringForRegion:
(...)
In iOS 6, regions with a radius between 1 and 400 meters work better on iPhone 4S or later devices. (In iOS 5, regions with a radius between 1 and 150 meters work better on iPhone 4S and later devices.) On these devices, an app can expect to receive the appropriate region entered or region exited notification within 3 to 5 minutes on average, if not sooner.
startMonitoringForRegion:
(……)
在 iOS 6 中,半径在 1 到 400 米之间的区域在 iPhone 4S 或更高版本的设备上效果更好。(在 iOS 5 中,半径在 1 到 150 米之间的区域在 iPhone 4S 及更高版本的设备上效果更好。)在这些设备上,应用程序可以期望在平均 3 到 5 分钟内收到适当的区域进入或区域退出通知,如果不早点。
回答by James Perih
Based on @Nevan's answer, which indicated some sort of coverage in WWDC 2013 307 (which didn't directly address this), I came up with a reasonable solution to getting < 10m accuracy for the arrival to a location, though I have a feeling that implementing -(void)locationManager:didVisit:
might make this more battery-conservative, but would provide less frequent updates.
根据@Nevan 的回答,该回答表明 WWDC 2013 307 中的某种报道(没有直接解决这个问题),我想出了一个合理的解决方案,使到达某个位置的准确度 < 10m,尽管我有一种感觉这种实施-(void)locationManager:didVisit:
可能会使电池更加保守,但会提供更少的更新频率。
First, have some regions with 0..150m radius, and start monitoring. Doesn't really matter, as the system seems to trigger these at around 150~200m:
首先,有一些半径为 0..150m 的区域,并开始监控。并不重要,因为系统似乎在 150~200m 左右触发这些:
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:CLLocationCoordinate2DMake(location.lat, location.lng) radius:50 identifier:location.name];
[_locationManager startMonitoringForRegion:region];
Then, implement
然后,实施
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
for (CLCircularRegion *enteredRegion in _locationManager.monitoredRegions.allObjects) {
if ([enteredRegion.identifier isEqualToString:region.identifier]) {
self.locationManager.activityType = CLActivityTypeFitness;
self.locationManager.distanceFilter = 5;
[self.locationManager startUpdatingLocation];
break;
}
}
}
The system will start monitoring and reporting to your delegate a stream of locations, even if your app is suspended (need UIBackgroundModes
to include location
array element).
系统将开始监视并向您的委托报告位置流,即使您的应用程序已暂停(需要UIBackgroundModes
包含location
数组元素)。
To check if one of those locations is within the centre of one of your regions, Implement:
要检查这些位置之一是否位于您所在地区之一的中心,请实施:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
CLLocation *firstLocation = [locations firstObject];
CGFloat const DESIRED_RADIUS = 10.0;
CLCircularRegion *circularRegion = [[CLCircularRegion alloc] initWithCenter:firstLocation.coordinate radius:DESIRED_RADIUS identifier:@"radiusCheck"];
for (CLCircularRegion *enteredRegion in _locationManager.monitoredRegions.allObjects) {
if ([circularRegion containsCoordinate:enteredRegion.center]) {
[_locationManager stopUpdatingLocation];
NSLog(@"You are within %@ of %@, @(DESIRED_RADIUS), enteredRegion.identifier);
break;
} else if ([enteredRegion containsCoordinate:circularRegion.center]) {
NSLog(@"You are within the region, but not yet %@m from %@", @(DESIRED_RADIUS), enteredRegion.identifier);
}
}
}
You'll also want to implement:
您还需要实施:
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
[_locationManager stopUpdatingLocation];
}
回答by Omeriko
In the past few days iv'e been testing a geofencing feature on my iOS 8.1 device (iPhone 5S) for an app iv'e developed.
The app is registering few regions to the iOS gefence service. The app's logic needs that each geofence radius is between 40 to 80 meters.
I'm seeing so far that in areas with larger number of cell towers and Wifi hot-spots, the geofence detection is good enough on entering regions. That is, in down town areas, business areas etc' the geofence detection is working fine.
在过去的几天里,我一直在我的 iOS 8.1 设备 (iPhone 5S) 上为我开发的应用程序测试地理围栏功能。
该应用程序正在向 iOS gefence 服务注册几个区域。该应用程序的逻辑需要每个地理围栏半径在 40 到 80 米之间。
到目前为止,我看到在蜂窝塔和 Wifi 热点数量较多的地区,地理围栏检测在进入区域时已经足够好了。也就是说,在市区、商业区等,地理围栏检测工作正常。
Unfortunately, the opposite occurs in areas with few cell towers & wifi networks. My neighborhood, for example, is about 1000 meters width and 500 height (1KM x 0.5KM), and there are no cell towers in it. There are few cell towers thought, on the perimeter that surrounds the neighborhood. Unfortunately In the perimeter of the neighborhood the geofence service detects nothing.
不幸的是,相反的情况发生在手机信号塔和 wifi 网络很少的地区。例如,我的社区大约有 1000 米宽和 500 米高(1KM x 0.5KM),而且里面没有信号塔。在围绕社区的周边几乎没有手机塔。不幸的是,在社区周边,地理围栏服务没有检测到任何东西。
Needless to say that i'm testing with Wifi enabled on the device.
不用说,我正在测试设备上启用了 Wifi。
When i test my app on Android: the geofencing service on android 4.3, 4.4 & 5.1 works much better than on iOS. The Android's geofencing service does not detect 100% of region transitions, however it detects 50%-90% of the region transitions.
当我在 Android 上测试我的应用程序时:Android 4.3、4.4 和 5.1 上的地理围栏服务比 iOS 上的要好得多。Android 的地理围栏服务不会检测到 100% 的区域转换,但是它会检测到 50%-90% 的区域转换。
I conclude the following: If there would have been more cell towers & Wifi hot-spots & if Apple would have improved the geofence service then the detection on iOS devices would have been as good as in Android's.
我得出以下结论:如果有更多的手机信号塔和 Wifi 热点,如果 Apple 改进了地理围栏服务,那么 iOS 设备上的检测就会和 Android 一样好。
回答by Abhi Beckert
Geofencing works by detecting a user moving from one cell network tower to another cell network tower.
地理围栏的工作原理是检测用户从一个蜂窝网络塔移动到另一个蜂窝网络塔。
Therefore smallest area you can define is dictated by how close together the cell towers are.
因此,您可以定义的最小区域取决于基站之间的距离。
Inside a shopping mall or sports stadium, it might be able to do 10 metres —?cell towers are often extremely close together. In a regional area anything smaller than 100km can fail.
在购物中心或体育场内,它可能能够达到 10 米——手机信号塔之间通常非常接近。在偏远地区,任何小于 100 公里的地方都可能出现故障。
If you need smaller areas, you need to use bluetooth instead of cell towers (iBeacons). If there is a bluetooth low energy device in the target area you can set the range to very short (centimetres) or reasonably large (up to 30 metres or so). Note this all depends on the quality of the iBeacon hardware, some are better than others.
如果您需要较小的区域,则需要使用蓝牙而不是手机信号塔 (iBeacons)。如果目标区域中有蓝牙低功耗设备,您可以将范围设置为非常短(厘米)或相当大(最多 30 米左右)。请注意,这完全取决于 iBeacon 硬件的质量,有些比其他的要好。
Unfortunately bluetooth (version 4.0 or newer) and cell network towers are the only way to monitor locations without significantly draining battery. Keeping the GPS active to check for a 10 metre boundary would drain the battery from full to completely flat in about 2 hours even with the screen switched off.
不幸的是,蓝牙(4.0 版或更新版本)和蜂窝网络信号塔是在不显着耗尽电池电量的情况下监控位置的唯一方法。保持 GPS 处于活动状态以检查 10 米边界会在大约 2 小时内将电池从充满电耗尽到完全没电,即使屏幕关闭。