Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 7 Region Monitoring Doesn't Reliably Fire

I have setup an app that only has region monitoring and nothing else. I am testing by running in front mode (as opposed to background mode). It is running on an iphone 5 with ios 7.0.4. It has background app refresh and location service and location authorization to this app enabled.

I have observed something really strange. When I use a simulator to cross boundaries, sometimes didEnterRegion/didExitRegion got called. But sometimes it just never get called no matter how many times I switch in and out of the boundary in simulation. There are times when it is called significantly late (several minutes) after I changed simulation.

I examined monitoredRegions to make sure the region I want to monitor is valid, and it is. The region monitored is around 100m radius. I use 2 simulation points, 1 inside, 1 in a different city. I used startMonitoringForRegion for monitoring the region.

Am I missing something here?

like image 588
Paul Jianer Shi Avatar asked Dec 06 '13 23:12

Paul Jianer Shi


1 Answers

Determining the Availability of Region Monitoring

Before attempting to monitor any regions, your app should check whether region monitoring is supported on the current device. Here are some reasons why region monitoring might not be available:

The device doesn’t have the necessary hardware to support region monitoring. The user denied the app the authorization to use region monitoring. The user disabled location services in the Settings app. The user disabled Background App Refresh in the Settings app, either for the device or for your app. The device is in Airplane mode and can’t power up the necessary hardware. In iOS 7.0 and later, always call the isMonitoringAvailableForClass: and authorizationStatus class methods of CLLocationManager before attempting to monitor regions. (In OS X v10.8 and later and in previous versions of iOS, use the regionMonitoringAvailable class instead.) The isMonitoringAvailableForClass: method tells you whether the underlying hardware supports region monitoring for the specified class at all. If that method returns NO, your app can’t use region monitoring on the device. If it returns YES, call the authorizationStatus method to determine whether the app is currently authorized to use location services. If the authorization status is kCLAuthorizationStatusAuthorized, your app can receive boundary crossing notifications for any regions it registered. If the authorization status is set to any other value, the app doesn’t receive those notifications.

Note: Even when an app isn’t authorized to use region monitoring, it can still register regions for use later. If the user subsequently grants authorization to the app, monitoring for those regions will begin and will generate subsequent boundary crossing notifications. If you don’t want regions to remain installed while your app is not authorized, you can use the locationManager:didChangeAuthorizationStatus: delegate method to detect changes in your app’s status and remove regions as appropriate. Finally, if your app needs to process location updates in the background, be sure to check the backgroundRefreshStatus property of the UIApplication class. You can use the value of this property to determine if doing so is possible and to warn the user if it is not. Note that the system doesn’t wake your app for region notifications when the Background App Refresh setting is disabled globally or specifically for your app.

for more see Apple docs

to prevent spurious notifications, iOS does not deliver region notifications until certain threshold conditions are met. Specifically, the user’s location must cross the region boundary and move away from that 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.

Monitoring of a geographical region begins immediately after registration for authorized apps. However, don’t expect to receive an event right away, because only boundary crossings generate an event. In particular, if the user’s location is already inside the region at registration time, the location manager doesn’t automatically generate an event. Instead, your app must wait for the user to cross the region boundary before an event is generated and sent to the delegate. To check whether the user is already inside the boundary of a region, use the requestStateForRegion: method of the CLLocationManager class.

Be judicious when specifying the set of regions to monitor. Regions are a shared system resource, and the total number of regions available systemwide is limited. For this reason, Core Location limits to 20 the number of regions that may be simultaneously monitored by a single app. To work around this limit, consider registering only those regions in the user’s immediate vicinity. As the user’s location changes, you can remove regions that are now farther way and add regions coming up on the user’s path. If you attempt to register a region and space is unavailable, the location manager calls the locationManager:monitoringDidFailForRegion:withError: method of its delegate with the kCLErrorRegionMonitoringFailure error code.

like image 197
Hashim MH Avatar answered Oct 26 '22 09:10

Hashim MH