IBeacon region monitoring not work consistently across devices
core-location, ios, ipad, iphone, objective-c
Solution
I Found the problem. Apparently to use iBeacons in the way that is described in the documents users are required to have the Background Refresh setting enabled in the Settings. To check for this setting I use the following snippet:
if ([[UIApplication sharedApplication] backgroundRefreshStatus] == UIBackgroundRefreshStatusAvailable) {
NSLog(@"Background updates are available for the app.");
}else if([[UIApplication sharedApplication] backgroundRefreshStatus] == UIBackgroundRefreshStatusDenied)
{
NSLog(@"The user explicitly disabled background behavior for this app or for the whole system.");
}else if([[UIApplication sharedApplication] backgroundRefreshStatus] == UIBackgroundRefreshStatusRestricted)
{
NSLog(@"Background updates are unavailable and the user cannot enable them again. For example, this status can occur when parental controls are in effect for the current user.");
}
Found in this answer: Detecting user settings for Background App Refresh in iOS 7
Problem
When testing with a simple app to test beacon region monitoring I seem to get very inconsistent results depending on the device (not the device model, the specific device). The problem is that I don't receive the `CLRegionStateInside` state on the region after `requestStateForRegion` and `didEnterRegion` does not get called at all on these device. `startRangingBeaconsinRegion`: works fine but to conserve power and processing it is recommended to only start ranging when the `didEnterRegion`: method gets called. I tested this on 6 devices and it works on half on them (iPhone 5's) and does't work on one iPhone 5, one `5S` and one `4S`. The beacons I use are the `kontakt.io` beacons. This is the code to setup the region monitoring ``` self.locationManager = [[CLLocationManager alloc] init]; self.locationManager.delegate = self; NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:BEACON_UUID]; CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"regionIdentifier"]; region.notifyOnEntry = YES; region.notifyOnExit = YES; region.notifyEntryStateOnDisplay = YES; [self.locationManager startMonitoringForRegion:region]; [self.locationManager requestStateForRegion:region]; //If I enable this line, ranging starts on all devices // [self.locationManager startRangingBeaconsInRegion:region]; ```