iBeacons ranging in background sometimes has delay - ios

I have an iBeacons app able to range for beacons while in background or not running. I implemented UILocalNotifications and they work fine, meaning i get a notification when i reach the range of a beacon.
Not having a real beacon i created an app (for another device, let's say an iPad for the next scenario) that acts like 2 different beacons, meaning it can broadcast 2 different signals, same UUID but different Major/Minor values (call this beacon A and B), one at a time obviously. My problem is in this scenario:
Have my iPhone (with iBeacons app closed) in lock screen
Activate my iPad app, broadcasting beacon A
My iPhone reacts showing me a notification
I stop iPad app from broadcasting beacon A, wait 1 second, start broadcasting beacon B
My iPhone DOESN'T react
I stop iPad from broadcasting
A few minutes later (about 2) my iPhone shows me the notification of beacon B
Now what i don't understand is this delay, the first time my iPhone reacts immediately, the second time it takes about 2 minutes to notify me the beacon.
If, after beacon B notification, i re-start broadcasting a beacon (A or B) my iPhone reacts immediately, then for the next time it always waits for 2 minutes.
Why is this happening? I've read some article saying that it's because the bluetooth awakes every 2-4 minutes while the app is in background, so i can get the info not faster than this time. But i don't see much sense in this because whenever i get the second notification the broadcasting of the beacon (B in my scenario) was already stopped, it means that if the bluetooth awakes in that very moment no beacon was in the air! But i get the notification, so it means that in someway my iPhone found it before i stopped the broadcasting.
Is this a problem that can be solved?
EDIT with some code
Here is my viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
// Initialize location manager and set ourselves as the delegate and beacons dictionary
_beacons = [[NSMutableDictionary alloc] init];
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// Create a NSUUID with the same UUID as the broadcasting beacon
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:#"6C1AA496-1653-403D-BD1E-7F630AA6F254"];
// Setup a new region with that UUID and same identifier as the broadcasting beacon
self.myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
identifier:#"testregion"];
NSLog(#"startMonitoring");
// Tell location manager to start monitoring for the beacon region
[self.locationManager startMonitoringForRegion:self.myBeaconRegion];
[self.locationManager startRangingBeaconsInRegion:self.myBeaconRegion];
_myBeaconRegion.notifyEntryStateOnDisplay = YES;
// Check if beacon monitoring is available for this device
if (![CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]]){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Monitoring not available" message:nil delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles: nil]; [alert show]; return;
}
}
Now whenever i get a beacon i send a notification, i just wanted to try how it worked so i didn't implemented yet a way to send just 1 notification, it means i get about 9 notification, 1 per sec that's the active time the code can run while in background i suppose (1 second enter region, 9 ranging for beacons)
-(void)locationManager:(CLLocationManager*)manager
didRangeBeacons:(NSArray*)beacons
inRegion:(CLBeaconRegion*)region
{
if([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground){
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = #"Found Beacon";
notification.soundName = #"Default";
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
}
Actually to be more specific, if i totally close my app from the multitasking view, or just let it in background, as soon as i start broadcasting a beacon i get the notification**S** (1 second delay). Then stopping the broadcasting and re-play the delay becomes in the order of minutes.
Now for a real scenario, where i should have many beacons in the same place, this delay could be a problem, as long as i get the notification when i could be already far away from the beacons itself.
Has my code any problem? I read those articles but i never found a delay of 15 minutes.
EDIT2 after davidgyoung suggestions
I modified my code and as you said using 2 different regions for beacon A and B the delay is always null. I also logged with the piece of code you gave and i discovered this.
Broadcast the beacon of Region_1
Device shows me the notification of Region_1
Stop broadcasting the beacon of Region_1
The logs say i'm still in the region, only after a couple of minutes i get the log "OUTSIDE Region_1", just now i can re-play the broadcasting to get another notification from Region_1.
So i was curious about this and i read and article http://beekn.net/2014/03/apple-ios-7-1-launches-major-ibeacon-improvement/
The author says that from iOS 7.1 the responsiveness of exiting a region is immediate, actually i'm running 7.1 but i also have a couple of minutes delay. Why this? Did you find the same problem in your tests?
Now, i read that a device can listen for no more than 20 regions right?it means that if i have 100 beacons i can set up just 20 regions and divide these 100 in 20 groups, getting no more than 20 notification (assuming these 100 are in the same place, all in the range of my device) ? That could be a problem because will force the user to run the app in the foreground to get all the information (assuming again each of the 100 beacons have a particular and unit role), am i right?

EDIT: This is my first answer before seeing the code.
I cannot explain this behavior based on your description, but I suspect there may be an issue with the setup that is either delaying your local notification or inaccurately reporting the state of beacon region B when the notification is sent.
Two things would help verify/eliminate this possible cause:
Add NSLog statements in your didDetermineState: forRegion: callback like below, then repeat your test reporting the log results.
// put this in your AppDelegate
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
if(state == CLRegionStateInside) {
NSLog(#"locationManager didDetermineState INSIDE for %#", region.identifier);
}
else if(state == CLRegionStateOutside) {
NSLog(#"locationManager didDetermineState OUTSIDE for %#", region.identifier);
}
else {
NSLog(#"locationManager didDetermineState OTHER for %#", region.identifier);
}
}
Post the code that sets up monitoring and issues the notification on detection.
If you have not read this already, you may want to give a quick look to similar tests I have done to measure background detection times:
http://developer.radiusnetworks.com/2013/11/13/ibeacon-monitoring-in-the-background-and-foreground.html
http://developer.radiusnetworks.com/2014/03/12/ios7-1-background-detection-times.html

After seeing the code, I think a few issues are going on here:
The code defines only a single region that encompasses BOTH beacon A and beacon B, preventing independent region entry/exit monitoring callbacks, and stopping the phone from getting woken up when switching from transmitting beacon A to beacon B. This is critical, because this means that if you switch from transmitting beacon A to beacon B, iOS will consider itself still in the one region. This can prevent the phone from getting a monitoring event that will wake up the phone in the background.
There is no code in the ranging callback to check which beacon was visible, so it does not seem possible to know for sure which beacon caused the notification. The notification will fire even if the beacon array passed to the ranging callback method is empty (i.e. if no beacons are detected.)
Ranging generally does not work in the background. The only exception is for a few seconds right after entering/exiting a region. I suspect that the two minute delay you report is the time it takes for your iPhone to perform the next background scan for iBeacons (This delay can be 2, 4, or 15 minutes depending on phone state). After that next next scan is performed, a region transition is detected (probably an exit region notification because nothing is transmitting), and ranging starts up for 5 sec firing a notification.
This is all very difficult to test and troubleshoot without directly logging the of the monitoring region callbacks as mentioned in my first answer as well as the ranging callbacks, and logging the identifiers of the beacons detected. Make sure you understand which of these callbacks are firing in order for which beacons, and don't try to troubleshoot too much at once!
In addition to troubleshooting the individual callbacks first, I would also recommend:
Changing the code to have one region per beacon for maximum background responsiveness.
Putting the detected beacon identifiers in the notification so you know beacon caused the notification to fire.

DavidGYoung is correct. iOS7.1 will invoke your app when terminated upon sensing a beacon region traversal. But,and this is critical, iOS will ONLY invoke a terminated app when you ENTER or EXIT a beacon region, and only if your app has previously registered for location events for that particular beacon region.
In your explanation above, it looks like you are only monitoring for ONE beacon region (you did not specify Major/minor numbers so any beacon with the same UUID will qualify). Unfortunately you created two beacon transmitters with the same UUIDs. So when you started the beacon you got ONE notification (ENTER) but had to wait a couple minutes for another (EXIT). typically I've seen exit notifications about 30 sec after a beacon stops transmitting.
If you want to perform the experiment again, try registering for TWO different beacon regions (declare two regions with diff Major/Minor numbers, or make two diff UUIDs), and then use these two diff values in your beacon transmitter. Should work then.
Tom

Related

Beacon Region Monitoring Get Delayed and randomly not working.(Android is working fine)

I have developed on application which is also developed in android.
I have implemented the beacon region monitoring in iOS as follows.
#pragma mark - Start/Stop Monitoring
- (void)startMonitoring {
[self clearRegionWatch]; // This function removes the already registered monitored regions
NSArray *arrayOfSavedBeacons = [self getSavedBeacons];
if([arrayOfSavedBeacons count]){
for(Beacons *beaconModel in arrayOfSavedBeacons) {
beaconModel.region.notifyOnEntry = YES;
beaconModel.region.notifyOnExit = YES;
beaconModel.region.notifyEntryStateOnDisplay = NO;
NSLog(#"Monitoring start request: %#", [beaconModel dictionaryRepresentation]);
[locationManager startMonitoringForRegion:beaconModel.region];
[locationManager requestStateForRegion:beaconModel.region];
}
}
else{
UIAlertView* curr1=[[UIAlertView alloc] initWithTitle:#"No Beacons" message:#"No Beacon List Found From Server" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[curr1 show];
}
}
Above is the code that starts the monitoring.
Following is the code that i have written for Initialization of Location Manager Instance.
locationManager = [[CLLocationManager alloc] init];
if([locationManager respondsToSelector:#selector(startMonitoringVisits)]) {
//iOS 8.0 onwards
[locationManager startMonitoringVisits];
}
if([locationManager respondsToSelector:#selector(allowsBackgroundLocationUpdates)]) {
//iOS 9.0 onwards
locationManager.allowsBackgroundLocationUpdates = YES;
}
if([locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
//iOS 8.0 onwards
[locationManager requestAlwaysAuthorization];
}
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager setDelegate:self];
[locationManager startUpdatingLocation];
Above code will initialise the location manager when app will start.
I want to get notified for the region entry and exit event.
My issue is my android app can detect the beacon entry from very long distance while iOS app can not detect the region enter or exit from far.
I don't know why this difference is coming?
What i have observed is beacon region monitoring sometime delayed the entry exit notifications by 2 to 3 minutes.
if android can detect the beacon region at particular range then why iOS app can not detect this?(it is significant difference in range form where both app can start to detect the app).
Any advice or suggestion would be helpful.
Thanks.
With iOS CoreLocation, the didEnterRegion monitoring callback is made upon first detection of a beacon matching the region regardless of the signal strength of the beacon advertisement. The callback should fire when the bluetooth chip first sees an advertisement at all, and this should be at a similar range for both iOS and Android devices. While the maximum bluetooth detection range certainly varies between devices, and can be affected by adding a case, putting your phone in your pocket, or by obstructions, in typical use it does not vary a great deal.
A more likely explanation why you are seeing delays in detections is timing, not signal strength. In the background, iOS will defer to a bluetooth chip hardware detection slot to quickly match your beacon region. This is a limited resource, so if these are exhausted, iOS will fall back to periodic software scans to detect, which can take up to 15 minutes. You can confirm this hypothesis by placing your iOS device at the same location where Android first detects, and simply waiting to see if it eventually tests at that distance.
A few tips to make your detections faster:
Uninstall all apps that may monitor beacons on your iOS device, as they may be using up the limited hardware acceleration slots. (Approx. 30 across all apps on the device.)
Don't stop monitoring and restart unless you absolutely have to. This will put your app last in line to get a hardware acceleration detection slot.
Start ranging for beacons when you start monitoring. This won't affect background detection times, but will significantly speed up foreground detection times.
If your app is in the background while you are ranging, it can take up to 15 minutes to get region notification of enter and exists. If your app is running in the foreground ,you should get entered region notifications within a second, and exit region notifications within a few seconds.
It is not beaconSpecific issue but the way of CoreLocation API is implemented in iOS.

It's that possible to detect a background beacon source generated by an iOS device

I try to use an iOS device as a beacon(let's say my iPhone5), which should be detected by another iOS devices, let's say (my iPad).
When both the devices are in foreground, my iPad is able to detect the beacon signal generated by my iPhone correctly. From my didRangeBeacons delegate method, I did
func locationManager(manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], inRegion region: CLBeaconRegion) {
if beacons.count > 0{
print(beacons)
}
}
I logged the beacon info
[CLBeacon (uuid:<__NSConcreteUUID 0x124e483b0> AD065817-291B-4422-BD59-CBBFBDB81F17, major:9, minor:6, proximity:2 +/- 0.81m, rssi:-56)]
When my iPhone(the beacon) in a background mode(the screen is not active), I am not able to detect any beacon signal from my iPad, are there any solution for this scenario? I have done a lot of research online, but I couldn't find something that is illuminating.
Monitoring for beacons works when an app is in the background because iOS is performing that service for the app. However ranging only works when the app is in the foreground. If short term background ranging is not enough then you need to enable the Background Modes option in the Capability tab of your project settings and use UIBackgroundModes set to location in your Info.plist.
Yes, you can range a beacon in the background. Normally iOS only allows you to do this for 10 seconds after you go to the background, however, you can use this code to extend your background awake time to up to 3 minutes:
func extendBackgroundRunningTime() {
if backgroundTask != UIBackgroundTaskInvalid {
// if we are in here, that means the background task is already running.
// don't restart it.
return
}
NSLog("Attempting to extend background running time")
var self_terminate: Boolean = true
self.backgroundTask = UIApplication.sharedApplication().beginBackgroundTaskWithName("DummyTask", expirationHandler: {() -> Void in
NSLog("Background task expired by iOS")
if self_terminate != nil {
UIApplication.sharedApplication().endBackgroundTask(backgroundTask)
self.backgroundTask = UIBackgroundTaskInvalid
}
})
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {() -> Void in
NSLog("Background task started")
while true {
NSLog("background time remaining: %8.2f", UIApplication.sharedApplication().backgroundTimeRemaining)
NSThread.sleepForTimeInterval(1)
}
})
}
You actually don't need background modes for this. You need to set NSLocationAlwaysUsageDescription in info.plist. Your phone will range any of the CLBeaconRegions you set it to look for. I like to use this app to test with iBeacons because it provides simulation and detection, although there are many beacon simulator apps out there, or you can buy an actual ibeacon.
I would try to use ranging in the background as sparingly as possible, because this process can be battery intensive if done in excess. Try to use monitoring in situations where you don't need to know things like Proximity and RSSI that are provided through ranging in order to conserve battery life.
Monitoring Beacons works well in foreground as well as in background.
Monitoring
Monitoring a region enables your app to know when a device enters or exits the range of beacons defined by the region. Imagine a museum with an audio guide application and beacons installed by the two entrances. The app is monitoring for a region encompassing both beacons (think: ‘all entrance beacons’ region) and is notified whenever the user enters the museum. Then it launches a notification, reminding users about the audio guide feature.
Ranging
While Monitoring enables you to detect movement in-and-out of range of the beacons, Ranging is more granular. It returns a list of beacons in range, together with an estimated proximity to each of them.Coming back to our museum example: imagine an "all beacons near the exhibits" region. The audio guide app can scan for all beacons in this region and then check which beacon is the closest. Since each beacon is associated with a particular exhibit, the app will play a description of an artwork relevant to the user’s context.
Ranging works only when the app is running, which most of the time means that the user is actively using the app. This also means that it only needs permission to "Access Your Location While You Use the App".
If you're sure you need persistent background ranging for beacons, you'll need to activate the Background Modes capability for your application—specifically, the Location Updates mode.
Note that for startRangingBeaconsInRegion to work in the background you'll also need to start Standard Location Updates via CLLocationManager's startUpdatingLocation (meaning you need both a CLLocationManager and an ESTBeaconManager in your app).
Note: In iOS 9, you also need to set the allowsBackgroundLocationUpdates property of your CLLocationManager to true.
(from community.estimote.com )
https://community.estimote.com/hc/en-us/articles/203914068-Is-it-possible-to-use-beacon-ranging-in-the-background-

iOS iBeacon Monitoring triggered randomly

I have a very strange behavior in my iOS application. While the beacon monitoring is working fine in most cases, there are sometimes hours where the didEnterRegion and didExitRegion events are fired multiple times in a row. The beacon itself is right next to the phone (about 15cm), so there shouldn't be an didExitRegion at all. I know that it is possible to loose a beacon signal what triggers an exit, but it's triggered about 5 times in 3 minutes (both enter and exit - so 10 calls). This is a very rare behavior and seems to be randomly.
The beacons are from Estimote and set via Estimote App to a broadcasting power of -20dBm what should be about 3.5 meters/ 12ft (according to Estimote App) and an advertising interval of 2000ms.
My init of CLLocationManager
if (! _locationManager) {
_locationManager = [[CLLocationManager alloc] init];
if ([_locationManager respondsToSelector:#selector(setAllowsBackgroundLocationUpdates:)]) {
// Not available in iOS 8
_locationManager.allowsBackgroundLocationUpdates = YES;
}
// For iOS 8
if ([_locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[_locationManager requestAlwaysAuthorization];
}
_locationManager.pausesLocationUpdatesAutomatically = NO;
_locationManager.delegate = self;
}
That's how i start monitoring
- (void)startMonitoringForBeaconRegions {
for (CLBeaconRegion *currentBeaconRegion in _beaconRegions) {
//default should be YES
currentBeaconRegion.notifyOnEntry = YES;
currentBeaconRegion.notifyOnExit = YES;
[_locationManager startMonitoringForRegion:currentBeaconRegion];
}
}
Does anyone have a similar behavior with their beacons and maybe a solution ??
Kind regards,
Kyaak
I observed a very occasional similar behavior in my demo/test apps. I experimented with setting beacons to max Tx power and 100 ms advertising interval, and it didn't help, which leads me to believe it might be a bug in Core Location itself. I've seen this erratic behavior with both Estimote SDK (which builds on top of Core Location), but also in pure Core Location.
It ordinarily takes 30 seconds of not "hearing" a beacon for an exit event to trigger, but in situations like these, I was observing enters and exits happening in rapid succession, like it completely ignored the 30-second timer, so I believe this is not actually caused by iOS not being able to "hear" the beacon.
I've also experimented with monitoring for CLCircularRegion instead of CLBeaconRegion (so, a GPS geofence instead of a beacon geofence) set up around my apartment and office, and I've observed the same, sporadic, erratic enters and exits.
Unfortunately, I haven't managed to figure out a fix/workaround for that yet. Maybe if we collectively start opening bug reports with Apple, they'll look into that.

iBeacon monitoring and ranging in background

I took several months developing an application based on iBeacons and I'm really frustrated.
The general idea is that when a beacon is detected, the user is notified with information specific to that iBeacon.
The application was designed as follows, all iBeacons have the same UUID, the Major determines the building (Museum, shop...) and the Minor the specific product (pictures, shoes...). So this application may serve multiple clients.
When the application starts, I begin to do monitoring and ranging for region with our UUID. When the app is in foreground all works perfect. But in background or suspended state the problems starts. Ranging is not allowed on background or suspended state.
I know that the app will be launched into the background for about 5 seconds when you enter or exit the region of a beacon. You can here do ranging in the background for this five second period, after which iOS will suspend your app again.
I managed to extend ranging for up to 3 minutes in the background with the technique learned here. I also get an extra callback with notifyEntryStateOnDisplay = YES;
But this is not enough, if a client enters a region with the app in background or suspended state, he will be notified. And during the extra 3 minutes he will be notified if the ranging detects another iBeacon, but when the 3 minutes background task expired, if no region exit is triggered he will not receive any notification again.
Is there no real solution in a scenario like this? I think it is a very common scenario and I'm surprised no way to deal with it.
EDITED: I tried to find a solution to the problem by monitoring two regions as recommended David Young in his response. In order to obtain more events of entry/exit regions.
I added the code I implemented to try to monitor two regions.
but something I have done incorrectly and didRangeBeacons:InRegion: callback is firing every 10 ms when the expected is every second.
On AppDelegate.m, I'm doing the following inside didFinishLaunchingWithOptions:
[self.locationManager startMonitoringForRegion:self.beaconRegion];
[self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
[self.locationManager startMonitoringForRegion:self.beaconRegion2];
[self.locationManager stopRangingBeaconsInRegion:self.beaconRegion2];
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion2];
Then, on didRangeBeacons:InRegion:
- (void) locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region{
if(beacons.count > 0){
[self.locationManager stopRangingBeaconsInRegion:region];
for (CLBeacon *beacon in beacons){
NSLog(#"beacon detected major: %# minor: %#", beacon.major,beacon.minor);
}
[self.locationManager startRangingBeaconsInRegion:region];
}
}
When I run the application on the simulator, and there is a beacon of each network in range, the message is displayed on the console approximately every 10 ms.
I suspect that the stop and restart the ranging is breaking the expected callback flow, but when only one region is in the range, callbacks occur every second as expected.
The problem you describe is common. The easiest approach is to extend background ranging time forever using a background location mode. (This is similar to what the OP has already done, but for an unlimited period of time.)
Two other options:
Get hardware beacons that allow you to tune down the transmitter power (my company's RadBeacon products allow this) so the transmissions do not overlap. This way you get an exit event then a new enter event as you move from beacon to beacon.
Redesign your identifier schene so the major field is dedicated to identifying up to 20 different regions (based on UUID and major 1-20). You then monitor for all of these regions. Your individual beacons can still use the minor however you want and specifically as the key to trigger messaging. When placing your beacons, you make sure that none with overlapping transmissions share the same major. This will ensure a new background entry event as you move from one to the other.
Beacon ranging in the background works just fine on iOS 8, provided you jump through all the hoops.
Firstly, you need the correct authorization. Add the key NSLocationAlwaysUsageDescription to your Info.plist, and call
[self.locationManager requestAlwaysAuthorization];
Your app must have a Background Mode of Location Updates. Specify in Info.plist or via the Capabilities (sits parallel alongside Build Settings).
Then check for authorisation in applicationDidBecomeActive with
switch([CLLocationManager authorizationStatus])
{
...
Once authorised, you need to do:
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// If you don't do this, location updates will pause after 15 minutes in the same place
// Usually this is what you want, so I've left this line commented out
// self.locationManager.pausesLocationUpdatesAutomatically = NO;
// Create a NSUUID with the same UUID as the broadcasting beacon
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:kProximityUUID];
_beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
identifier:#"uk.co.airsource.testregion"];
// Necessary to get continued background ranging.
// See https://community.estimote.com/hc/en-us/articles/203914068-Is-it-possible-to-use-beacon-ranging-in-the-background-
_locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
[_locationManager startUpdatingLocation];
[_locationManager startMonitoringForRegion:self.beaconRegion];

iOS 7.1 Geofencing and iBeacons stop working

I am working on a location services app and am finding some strange behavior. Once the user confirms using location services, the geofence icon appears in the status bar. Everything works great and I get enter and exit region events whether the app is running, in the background, or not in the background. But at some point the geofence icon disappears and my device is insensitive to the Beacon. Are there any conditions under which the geofence is disabled until I power cycle the device? And power cycling does bring it back.
This is a newly introduced bug in CoreLocation. Unfortunately, there is no known automated way to fix this. It requires a power cycle or Bluetooth off/on sequence to resolve.
See here.
I was having a similar problem. My app would work and locate beacons on initial run. When I rebooted, app opened to ScanViewController as expected but did not detect beacon.
I referenced article on StackOverflow, iBeacon: didRangeBeacons stops getting called, must reset device for it to work again and reviewed Apple's WWDC 2013 Video Session "What's new in Corelocation" https://developer.apple.com/videos/wwdc/2013/index.php?id=307
I found additional CLLocation delegate methods:
When you init your beacon region if you set:
notifyEntryStateOnDisplay = YES;
//The following delegate method will be called:
-(void) locationManager: (CLLocationManager *) manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region {
if (state ==CLRegionStateInside) {
[_locationManager startRangingBeaconsInRegion:region]:
}
//Your alternative code
}
//To help trouble shoot, I added this delegate methods
-(void) locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *) region withError: (NSError *)error {
}
and
-(void) locationManager:(CLLocationManager *)manager rangingBeaconsDidFailForRegion:(CLRegion *) region withError: (NSError *)error {
}
I ran app. It returned no failure errors. I checked settings. Bluetooth was enabled and detecting BT devices.
I checked the status bar for geofencing icon. The geofencing icon was present.
I waited for over 2 minutes and then the app detected the beacons and worked as expected. Sluggish is an understatement. I knew that rebooting should work according to all the iOS 7.1 articles that I read in StackOverFlow and other resources.
I rebooted and waited for the app to detect the beacons. On average it took 2 minutes until beacon detection. I am not sure what is causing this slow response. Since must app responses are measured in fractions of seconds, I am sure that developers may think that their apps are not working.
I suggest if your app does not detect beacons or return failure errors that you wait 2 minutes to see if you app will detect the beacon(s). I hope this helps.

Resources