Aprove answer

The beacon.proximity field will be updated with each callback to func locationManager(_: CLLocationManager, didRangeBeacons: [CLBeacon], in: CLBeaconRegion). These callbacks will come once per second with an array of CLBeacon objects that have this field. So every 1 second you will get an update.

Based on the way the code is set up, it appears that beaconsInProximity will be updated properly if the beacon is in immediate proximity and switchLamp will be called later in the callback method.

Understand, however, that the CLBeacon's proximity field may not update as quickly as you'd like. This field is derived from the accuracy field, which is a distance estimate in meters. If the distance estimate is < 0.5 meters, then accuracy will be set to immediate. If the distance estimate is > 0.5 meters, it will be set to another value.

The distance estimate in accuracy is based on a 20 second running average of the RSSI measurements. Because of this, if you very quickly move from 5 meters away to right next to the beacon transmitter, the accuracy field will slowly change from ~5.0 to ~0.0 over the course of 20 seconds. It will take nearly 20 seconds for the proximity field to show immediate.

Also, it is important to understand that the beacon must be calibrated properly with the measuredPower value set inside the beacon for as accurate distance estimates as possible. If you are getting very inaccurate distance estimates in accuracy even after staying still for 20 seconds, then you may need to do this calibration.

Credit Goes to: stackoverflow.com

Related question with same questions but different answers