MY QUESTION IS: How can I enable continuous monitoring from the central while the phone is locked (no display turned on) or while its in the background?
First of all, I am using the iBeaconDemo courtesy of Christopher Mann @ https://github.com/csmann/iBeaconDemo and I take no credit for writing this demo, but I am using it to understand iBeacons and Region Monitoring. It is a great demo, but I wish it had background monitoring enabled to show a local notification when you enter the Near range.
I have enabled bluetooth-central, bluetooth-peripheral and locations in my Capabilities (info.plist) file and have set .notifyOnDisplay, notifyOnEntry and notifyOnExit to YES and have found that I get results while the app is in the foreground or on the lock screen (pressing the home button while the phone is locked) but I cannot get it to monitor while it is in the background (phone is unlocked) or while the phone is locked (no display on).
This is my appDelegate's didEnterBackground method (note: this is a different local notification and this one works correctly every time but not the same as the notification I want to be displayed when I enter the region:
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(@"Application entered background state.");
[[UIApplication sharedApplication] cancelAllLocalNotifications];
// create local notification and present it immediately
UILocalNotification *notification = [self createLocalNotification:@"Bring app back to foreground"];
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
Here are the notifications I want to present while in the background, I just need 1 notification to pop up once I enter the region (I put 1 in each for testing purposes):
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
// identify closest beacon in range
if ([beacons count] > 0) {
CLBeacon *closestBeacon = beacons[0];
if (closestBeacon.proximity == CLProximityImmediate) {
/**
Provide proximity based information to user. You may choose to do this repeatedly
or only once depending on the use case. Optionally use major, minor values here to provide beacon-specific content
*/
[self fireUpdateNotificationForStatus:[NSString stringWithFormat:@"Range: %li \n Beacon Name: %@ \n You are in the immediate vicinity of the Beacon.", (long)closestBeacon.rssi, ((CLBeaconRegion*)region).identifier]];
[[UIApplication sharedApplication] presentLocalNotificationNow:[self createLocalNotification:@"Immediate LN"]];
} else if (closestBeacon.proximity == CLProximityNear) {
// detect other nearby beacons
// optionally hide previously displayed proximity based information
[self fireUpdateNotificationForStatus:[NSString stringWithFormat: @"Range: %li \n Beacon Name: %@ \n There are Beacons nearby.", (long)closestBeacon.rssi, ((CLBeaconRegion*)region).identifier]];
[[UIApplication sharedApplication] presentLocalNotificationNow:[self createLocalNotification:@"Near LN"]];
} else if (closestBeacon.proximity == CLProximityFar) {
[self fireUpdateNotificationForStatus:[NSString stringWithFormat:@"Range: %li \n Beacon Name: %@ \n You are far away from the %@th beacon in store %@!", (long)closestBeacon.rssi, ((CLBeaconRegion*)region).identifier, closestBeacon.minor, closestBeacon.major]];
[[UIApplication sharedApplication] presentLocalNotificationNow:[self createLocalNotification:@"Far LN"]];
}
} else {
// no beacons in range - signal may have been lost
// optionally hide previously displayed proximity based information
[self fireUpdateNotificationForStatus:@"There are currently no Beacons within range."];
}
}
Lastly, here is the fireUpdateNotificationsForStatus method incase this may be useful:
- (void)fireUpdateNotificationForStatus:(NSString*)status {
// fire notification to update displayed status
[[NSNotificationCenter defaultCenter] postNotificationName:kLocationUpdateNotification
object:Nil
userInfo:@{@"status" : status}];
}
If there is anything else that would be useful to help out, please feel free to let me know. Thank you for your time!