didEnterRegion and didExitRegion are not being called


Yep! Xcode 7, but when I use Xcode 6, they are not being called too. I don’t understand why? But ranging still work well


@phongnguyendev, if ranging works but monitoring doesn’t, can you double check if you app has the “always” authorization to access location services, instead of the “when in use” authorization? Can you implement the didStartMonitoring, monitoringDidFail, and didDetermineState methods and see if these get called?

@phongnguyendev & @Ricardo_Costa, what iOS devices do you guys use? What iOS version? Can you try calling requestStateForRegion—it should force a call to the didDetermineState, does it say “outside” or “unknown” then?


well @heypiotr. I’m using “always” like this [self.estBeaconManager requestAlwaysAuthorization];
And I’m testing with iPad 4 Gen iOS 8.4, and with requestStateForRegion, it return CLRegionStateInside. It’s fine with requestState right?


im using ipad mini with iOS 8.1 and when i call requestStateForRegion it enters in didDetermineState but the info that i get in the state variable is CLRegionState


One important thing to keep in mind, I’m not sure if you guys are aware of this behavior—if you do, then sorry for over-explaining (:

Enter and exit events are only triggered when the state changes, i.e., goes from inside to outside and vice versa. If you start monitoring with the beacon already in range, it won’t trigger an immediate enter. Same for exit—if you start monitoring and the beacon is out of range, there won’t be an immediate exit.

Furthermore, exit event has an internal delay of 30 seconds—so you need to leave the range of the beacon for at least 30 seconds in order for it to trigger.

I’ll try to illustrate this with an example:

  1. Let’s assume we’re starting with the beacon in range of the device.
  2. You call startMonitoring.
  3. Monitoring starts, and the state of the beacon region is determined to be “inside.” There should be a call to didDetermineState with this initial state, but there won’t be a call to didEnter.
  4. You move out of range of the beacon. As soon as you’re out, the clock starts ticking.
  5. When the clocks reaches 30 seconds, the state of the beacon region will change to “outside.” There will be a call to didDetermineState. Also, since the state changed from “inside” to “outside,” there will be a call to didExit.
  6. Now you move back in range. The state changes to “inside” again. There will be a call to didDetermineState. And again, since the state changed from “outside” to “inside,” there now will be a call to didEnter.

Last but not least, for some devices, and in some special cases, it may actually take up to 15 minutes for iOS to acknowledge the state change. We know this to be the case for iPhone 4S, and I’m not sure about iPads. Newer iPhones (5, 5S, 6, etc.) usually respond immediately. Any chance you have some alternative iOS device at hand to test?


Well, thank I understand its mechanism. I shall give a try. So that because of state is “outside” so it doesn’t call didEnterRegion or didExitRegion. Thank you very much for your help, very kind of u @heypiotr.


i understand that but my didDetermineState don’t have the “inside” or “outside” value. when it triggers (with the use of requestStateForRegion) the state variable have the value CLRegionState


In Swift, you need to use state.rawValue. 0 = unknown, 1 = inside, 2 = outside.


ok the value is 0 so its unknown, and i have the beacon close to my ipad


The only thing that really comes to my mind at this point is a bug in iOS. In fact, I’ve experienced something similar with iPhone 4S and iOS 8.0, where my app just couldn’t establish the state no matter how hard I tried. My problem was fixed in iOS 8.1 or 8.2, don’t remember exactly. Maybe this is something similar, could you try opening a bug report with Apple?


well its was the ios version lool…i updated my ipad to ios 9.0.1 and my app and the estimote template works now thx a lot for your help :smile: great community

keep the good work


The above topic solved many of my questions. A part of it is working fine. The problems is i have to monitor two regions. whether i have to moniter them individually or both at the same time. Please help

let area = CLBeaconRegion(proximityUUID: NSUUID(UUIDString: "B9407F30-F5F8-466E-AFF9-25556B57FE6D")!, identifier: "bestpals")

let area1 = CLBeaconRegion(proximityUUID: NSUUID(UUIDString: "B9407F30-F5F8-466E-AFF9-25556B57FE6D")!, major:8693, minor:14142, identifier: "blue")
let area2 = CLBeaconRegion(proximityUUID: NSUUID(UUIDString: "B9407F30-F5F8-466E-AFF9-25556B57FE6D")!, major:30160, minor:48293, identifier: "grey")

override func viewDidLoad() {
    locationManager.delegate = self

func locationManager(manager: CLLocationManager, didStartMonitoringForRegion region: CLRegion) {
    c.text  = "moniterd : \(region.identifier)"

func locationManager(manager: CLLocationManager, didEnterRegion region: CLRegion) {
    a.text  = "entered region : \(region.identifier)"

func locationManager(manager: CLLocationManager, didExitRegion region: CLRegion) {
    b.text = "exited region : \(region.identifier)"

func locationManager(manager: CLLocationManager, didDetermineState state: CLRegionState, forRegion region: CLRegion) {
    switch state {
    case .Unknown:
        print("unknown : \(region.identifier)")
        state3.text = "unknown : \(region.identifier)"
    case .Inside:       
        print("inside : \(region.identifier)")
        state1.text = "inside : \(region.identifier)"
    case .Outside:
        print("outside : \(region.identifier)")
        state2.text = "outside : \(region.identifier)"


If you want separate enter/exit events for area1 and area2, just start monitoring for both of them:



but when i run the code only "locationManager.startMonitoringForRegion(area2)” calls… i.e, only area2 get monitored


It might seem that only area2 is being monitored, because you always overwrite the text.

For example, you start monitoring for area1, and didStartMonitoring is called for area1. Text is set to moniterd : blue.

Milliseconds after that, monitoring for area2 starts, and didStartMonitoring is called for area2. The previous text is overwritten and it now says to moniterd : grey.

Same for all the other events.

If you want to verify if both work, you can use NSLog instead:

NSLog("moniterd : \(region.identifier)")

This will log the messages in the Xcode’s console instead, and nothing will be overwritten.


Thank you. kinda helped me…


Hi heypiotr,
I connected the beacon to my phone it work fine, i enter in beacon range it trigger but after 1min didexitrange was trigger, but i am staying same place and also after 1min didenterrange was trigger.

It repeatedly occurred



Without Passing the Major / Minor didEnter or didExit not calling. But When I pass the Major - Minor it’s working fine. Can you say I have to pass major/minor for each beacons.



Without major/minor, the smartphone will scan for any beacons with the matching UUID, and as long as there’s at least one in range, won’t trigger an exit.

For example: you have two beacons in range:

  1. UUID X, major 1, minor 1
  2. UUID Y, major 1, minor 2

Case 1: you scan for UUID X + major 1 + minor 1. When beacon #1 leaves range, exit triggers.

Case 2: you scan for UUID X. When beacon #1 leaves range, there’s still beacon #2 matching the criteria, so no exit will be triggered.


Yes, But App in Killed state at that time it’s not working. I set the below configure.



 const region1 = {





 const region1 = {






 const region1 = {




 minor : 1