Question

I've simplified the question a bit. When I create and add regions in my app and interrogate the state of those regions I see the following in monitoringDidFailForRegion method:

The operation couldn’t be completed. (kCLErrorDomain error 4.)

Checking the CLErrorDomain constants I see that error 4 is kCLErrorRegionMonitoringDenied and it is described like so:

Access to the region monitoring service was denied by the user.

How is this possible? Here's my set up and what I've checked:

  • I am working through Xcode to watch log statements.
  • I am connected to my iPhone 5. I am not running in the simulator.
  • I have ensured that the radius is sufficient in size to be monitored (though it shouldn't matter).
  • I have ensured that Settings > Privacy > Location Services is on for my device and my app.
  • I've read every Core Location and Region Monitoring document Apple has ever published.
  • I have ensured that WiFi is on and that I have a strong cellular signal. If I didn't it wouldn't be able to find my location in the first place.
  • I have ensured that didChangeAuthorizationStatus reports the correct status: kCLAuthorizationStatusAuthorized
  • I have ensured that after adding my region that monitoring does in-fact begin by observing the call to the method didStartMonitoringForRegion.

What am I missing? Why do I see this error when Location Services are clearly enabled?

Was it helpful?

Solution

So, I took yet another look at the documentation on Region Monitoring and I noticed this in the highlighted item in the list:

Determining the Availability of Region Monitoring

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

  • The device may not have the hardware needed to support region monitoring.
  • The user might have denied the app the authorization to use region monitoring.
  • The user may have disabled location services in the Settings app.
  • The user may have disabled Background App Refresh in the Settings app, either for the device or for your app.
  • The device might be in Airplane mode and unable to power up the necessary hardware.

Then I checked that Background App Refresh (a new feature at iOS 7: Settings > General > Background App Refresh) is turned on and available for my app. It was not. I turned the feature on and BOOM my regions are reporting their state now.

It is confusing and misleading that:

[CLLocationManager isMonitoringAvailableForClass:[CLRegion class]] returns YES 

...even when Background App Refresh is disabled. I would think it would return NO.

UPDATE:

I have sent a bug report to Apple and added an Open Radar for this issue.

UPDATE 3-11-14:

Apple has confirmed that this is a bug.

OTHER TIPS

In order to do region monitoring (at least in iOS 9) you need to request "always" authorization. This not documented anywhere I could find, but it's the only way I was able to get region monitoring working.

rdar://23566600 - if you're inside apple :)

Try adding the appropriate entry in your info.list for the user prompts when granting permission to use the location services. These info.plist entries are (NSLocationWhenInUseUsageDescription and NSLocationAlwaysUsageDescription). I have noticed that the omission of the NSLocationUsageDescription entry did not have the same negative effect. good luck.

For my case help to setting "ALWAYS" "In order to do region monitoring (at least in iOS 9) you need to request "always" authorization" and 300 meters radius

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top