iOS: CoreLocation Framework and Beacon Detection

Beacon technology is one of the exciting technologies that have enabled location awareness possibilities for apps. Because of the increasing popularity of the technology, iBeacon was introduced, which extends CoreLocation Framework in iOS for beacon detection using monitoring and ranging. The signals from a beacon can now be monitored using any iOS device that supports Bluetooth 4.0.

Using CoreLocation Framework with iBeacon Technology:

To use iBeacon technology for beacon detection, we first need to import CoreLocation and CoreBluetooth into our project and include the header files of these frameworks in our ViewController header file.

#import <CoreLocation/CoreLocation.h>

#import <CoreBluetooth/CoreBluetooth.h>

Once these frameworks are included in the view-controller, we use CLLocationManager class for all the location-related activities. CLLocationManager class is the central point for configuring the delivery of location to our app. These are the main activities related with beacon detection for which support is provided by CLLocationManager class:

  1. Monitoring various regions and notifying whenever the user enters or leave the region.
  2. Reporting the range from nearby beacons.
  3. Deferring the delivery of location updates, even when the app is in background.

Since the above three activities are at the core of beacon detection, active location services are must for a robust application interacting with beacons.

Initialize Location Services: The first thing that we need to do is to initialize location manager and set ourselves as the delegate.

self.locationManager = [[CLLocationManager alloc] init];
self.loacationManager.delegate = self;

Setting distance filter and desired accuracy: Distance filter signifies the minimum distance required before an event is generated and desired accuracy sets the accuracy that we require of an application.

self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;

The other values that desired accuracy variable can have are-

  1. kCLLocationAccuracyBestForNavigation
  2. kCLLocationAccuracyBest
  3. kCLLocationAccuracyNearestTenMeters
  4. kCLLocationAccuracyHundredMeters
  5. kCLLocationAccuracyKilometer
  6. kCLLocationAccuracyThreeKilometers

Setting distance filter as kCLDistanceFilterNone signifies that we want to be notified as many times as possible hence, keeping the distance filter to the minimum.

Setup a Beacon Region:

Beacon region is the area around a beacon that is defined by the device’s proximity to the beacons. The process of detecting beacons by an application can be explained in two steps- Monitoring and Ranging. A beacon region can be defined as follows-

// Create a NSUUID with the same UUID as the broadcasting beacon
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:UUID];
// Setup a new region with that UUID and same identifier as the broadcasting beacon
    self.myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:BeaconRegionIdentifier];
// Notify whenever app enters or leaves a beacon region. 
    self.myBeaconRegion.notifyOnEntry = true;
    self.myBeaconRegion.notifyOnExit = true;

Keeping Location Services always active:

Whenever we need our application to continuously track someone’s movement, we require location services to be always active. But, because of heavy battery consumption, iOS kills the app after some time once the app is in background. Although keeping location services constantly active should be avoided (except in the cases when it’s necessary), it can be achieved by following certain steps.

In order to ensure that the app is continuously monitoring and ranging for beacons even when the app is in background (display of the device is still on), we need to set this property to true.

// Notify whenever app enters or leaves a beacon region. 
  self.myBeaconRegion.notifyEntryStateOnDisplay = true;

But, it is noticed that even after this, the application stops ranging for beacons once it is out of all the beacon regions.

// Notify whenever app enters or leaves a beacon region. 
// Tell location manager to start monitoring for the beacon region
    [self.locationManager startMonitoringForRegion:self.myBeaconRegion];
    [self.locationManager startRangingBeaconsInRegion:self.myBeaconRegion];

-(void)locationManager:(CLLocationManager*)manager didExitRegion:(CLRegion *)region
	[self.locationManager stopMonitoringForRegion:self.myBeaconRegion];

Once the ranging is stopped, it might take 30 seconds to 5 minutes for the app to retain ranging. In order to avoid this, we should make sure that the ranging for beacons is never stopped. In other words, we shouldn’t call

[self.locationManager stopMonitoringForRegion:self.myBeaconRegion];

in didExitRegion location manager delegate.

Apart from that, in order to make sure that iOS doesn’t stop location updates when the app is idle for some time and is in background, we should set this property as false.

self.locationManager.pausesLocationUpdatesAutomatically = false;

Exception in iOS 8:

It is observed that even after following above steps, the location services keep turning off in iOS 8 device. To make sure that the proper beacon detection takes place in iOS 8 devices too, we need to do two extra things –

  1. Add one or both of the below keys to Info.plist file –
    1. NSLocationWhenInUseUsageDescription
    2. NSLocationAlwaysUsageDescription

We also need these before starting location updates. The first one is for location updates in both the foreground and background, and the second one is for foreground location updates only.

    [self.locationManager requestAlwaysAuthorization];
    [self.locationManager requestWhenInUseAuthorization];

If the application supports various iOS versions, the above code snippet should be included only for iOS 8, as it will cause the application to crash for other iOS versions. One method to achieve this is as follows –

    if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
        [self.locationManager requestAlwaysAuthorization];

Once all this is done, start the location updates by calling this method.

[self.locationManager startUpdatingLocation];

Various delegates called on beacon detection:

-(void) locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *) region 


1. Whenever the app enters a beacon region, this delegate gets called.

2. This delegate is called as soon as the app is outside of all beacon regions.

-(void)locationManager:(CLLocationManager*)manager didExitRegion:(CLRegion *)region {

3. This delegate is called repetitively and gives the proximity of app from beacon and other details about the beacons.

didRangeBeacons: (NSArray *) beacons 
inRegion:(CLBeaconRegion *)region

Among the above three, the first two events are fired while monitoring for beacons and the third one is fired with beacon regions-ranging.

Sparsh Khandelwal

Sparsh Khandelwal

Software Engineer

Sparsh Khandelwal is a Software Engineer at 3Pillar Global. He has experience in .NET technology and iOS application development in Objective C. Sparsh is a graduate from the renowned Indian Institute of Technology (IIT), Delhi. He is an avid reader and loves to spend his time reading novels.

3 Responses to “iOS: CoreLocation Framework and Beacon Detection”
  1. Ahmed Hamdy on

    // Create a NSUUID with the same UUID as the broadcasting beacon
    I want only collect beacon ,why i use UUID ?

    • Sparsh Khandelwal on

      Every beacon can be provided with an UUID and then we mention in the app which UUID to listen to. It helps in avoiding listening to the beacons that aren’t the ones we want to listen to. For e.g., if there are two stores side by side with their own beacons, they don’t want their apps to interact with the beacons of another store.
      Having said that, it’s not possible to listen to beacons with any UUID. It is essential that we provide the app with some UUID.

  2. Vivek on

    Hi Sparsh,

    I have a question need to create an attendance marker using beacons.
    1)How can I keep the app running always?(I think its already in your blog)
    2)Do I need any sdk or I can use the iOS APIs directly?
    3)Will the location services security prompt me with Alerts for user permissions, now and then about my app using location services and need users acceptance again and again? Can this be avoided?

Leave a Reply

Related Posts

4 Reasons Everyone is Wrong About Blockchain: Your Guide to ... You know a technology has officially jumped the shark when iced tea companies decide they want in on the action. In case you missed that one, Long Isl...
3Pillar Recognized as a Leading Experience Designer by Forre... Fairfax-based product development company named to its second Forrester report in 2018 FAIRFAX, VA (June 18) - Today, 3Pillar Global, a global cust...
3 Cloud Optimization Projects That Will Pay for Themselves i... AWS introduced 1,430 new features and tools in 2017, including 497 in the 4th quarter alone. This means that it can be a challenge for even the mos...
The Connection Between Innovation & Story On this episode of The Innovation Engine, we'll be looking at the connection between story and innovation. Among the topics we'll cover are why story ...
Go Native (App) or Go Home, and Other Key Takeaways from App... I just returned from my first WWDC. I feel like I learned more in a week at Apple’s annual developer’s conference than I have in years of actually dev...