17

While testing with beacons (iOS devices) I found the listener beacon giving some unexpected behavior. locationManager:didEnterRegion method is not getting called even if a beacon enters a region. But the locationManager:didRangeBeacons:inRegion: is getting called correctly, and detected beacons are shown there. Has anyone experienced anything like this.

Dhanesh KM
  • 449
  • 2
  • 7
  • 18
  • After struggling with problem 1,5 days. The problem were with airplane mode. If airplane mode is on, iBeacon ranging perfectly working but monitoring not. It is shame that there is no error or whatsoever – bpolat Aug 26 '15 at 19:01

4 Answers4

33

Check if your methods are implemented in the following way. In viewDidLoad, start moniotoring at the end

self.beaconRegion.notifyOnEntry=YES;
self.beaconRegion.notifyOnExit=YES;
self.beaconRegion.notifyEntryStateOnDisplay=YES;
[self.locationManager startMonitoringForRegion:self.beaconRegion];

after monitoring start, request state for your defined region

- (void) locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
{
    [self.locationManager requestStateForRegion:self.beaconRegion];
}

after state is determined, start ranging beacons

-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
    if (state == CLRegionStateInside)
    {
        //Start Ranging
        [manager startRangingBeaconsInRegion:self.beaconRegion];
    }
    else
    {
        //Stop Ranging here
    }
}

and implement the following methods according to your needs...

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    self.statusLbl.text=@"Entered region";
}

-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    self.statusLbl.text=@"Exited region";
}

-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
    if(beacons.count>0)
    {}
}

Hope this will solve your problem.

Muhammad Ibrahim
  • 1,923
  • 2
  • 15
  • 13
12
before starting coding in project , you must follow given setup guidlines -->
1. in project info or info.plist -->
         Custom IOS Target Properties -->
                    . add "Required background modes"
                    . in this add two items -->
                                ."App shares data using CoreBluetooth"
                                ."App registers for location updates"
2. in project Capability -->
         There is Background Modes  
                   . check "Loaction update"  
                   . check "Acts as a Bluetooth LE accessory"
                   . check "uses bluetooth LE accessories"

(and do follow the instructions given by Mr. Davidgyoung. believe me, it will definitely work.)

Nitesh
  • 1,924
  • 21
  • 31
  • If your app is a BLE central, you need to set "App communicates using CoreBluetooth" in Required background modes. If your app is a BLE peripheral you need to set "App shares data using CoreBluetooth" – mezulu May 05 '17 at 18:57
  • I have add each of then still my did enter in region method not called – Anita Nagori Dec 16 '19 at 17:13
8

You also need to be aware that you are monitoring a region - not a particular beacons.

So if you have 3 beacons which share the same proximityUUID and your region is defined as only proximityUUID (without major and minor values) you will get notified only in two situations:

  1. No beacons from the region were in range and first beacon/beacons gets discovered (didEnterRegion:)

  2. One or more beacons from the region were in range and they all went out of sight for ~30 seconds (didExitRegion:)

Maciek Czarnik
  • 5,950
  • 2
  • 37
  • 50
7

It's hard to say if I have seen the exact same thing without more specifics about the starting conditions of your test. But, yes, in some specific cases, I have seen locationManager:didRangeBeacons:inRegion get called even without getting a call to locationManager:didEnterRegion.

If you start ranging and monitoring at the same time with the same region, and iOS thinks you were already in the monitored region, then you may not get a call to locationManager:didEnterRegion.

To truly test if something is amiss, you need to set up a test case where you:

  1. Make sure you are not in the region.
  2. Let iOS run for several minutes
  3. Start monitoring that region
  4. Let iOS continue to run for a few minutes
  5. Enter the region.
  6. See if you get a call to locationManager:didEnterRegion

If you still don't get a call after going through the above, then something is definitely wrong.

iYoung
  • 3,596
  • 3
  • 32
  • 59
davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • i started transmitting after i entered the region. In that case it is supposed to call.. right ? once i exit from the region by stopping the transmit and then i again start transmitting, its working as excpected (didEnterRegion is getting called). – Dhanesh KM Oct 09 '13 at 12:08
  • It doesn't matter if *you* think you entered the region. :) All that matters is what iOS LocationManager thinks, and its current state is invisible to you. You need to be 100% sure that it does not think it is already in the Region you defined when you start monitoring, because if it thinks it is already in the Region, you may not get a callback. That is why I suggest the procedure above -- it ensures that iOS will recognize you as being outside the region when the test starts. – davidgyoung Oct 09 '13 at 19:40
  • Let me ask this another way... if the problem you report is repeatable, what is the difference between what you say works in your comment and what you say doesn't work in your original post? Do you reboot your phone? Do you wait an extra long time? What does it take to repeat the failure? – davidgyoung Oct 09 '13 at 19:48
  • @davidgyoung my didEnterRegion delegate is not getting called? can you tell me how to detect where am I going wrong? – iYoung Jan 29 '15 at 10:42
  • I encountered same problem, and I found that from iOS8 we have to handle requestAlwaysAuthorization or requestWhenInUseAuthorization to get location information. And also we have to add NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription to info.plist. – tokentoken Mar 01 '15 at 14:05