Share this article:

Discovering the iBeacons in iOS

iBeacon is part of the CoreLocation framework in iOS. Using an iBeacon is similar to geofencing. But instead of using a GPS coordinate you are basing your proximity on receiving a Bluetooth LE signal. This makes it possible to detect proximity of moving targets by placing a beacon on them.

Read more Shop
Each beacon has three identifiers:

proximityUUID: a unique UUID to distinguish your beacons from those others are using.

major: used to group related sets of beacons

minor: used to identify a beacon within a group

The major and minor numbers are basically arbitrary numbers and your app will have to give those a meaning using tie-ins to your product or shop database for example.

Monitoring

You can monitor whether you are inside or outside region i.e. if any beacons are transmitting. I assume this is fairly low power

Ranging

Once in range you can “range” which means that you will get updates of all the matching beacons including details of their signal strength which is turned into a distance for you. To save power you should only range when inside a region. Also the beacons are often going to be transmitting at long intervals (1s or more) therefore the status will flip flop a bit so I would not take the inside and outside literally but would keep ranging until you are outside the range and then add on a timer of 5 or 10 seconds. Presumably in most situations you only need to know that you are in range once in order to show a coupon or an advertisement. After that you can ignore the beacons for a while.

In the header(.h) file


#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@interface glimbeaconViewController : UIViewController <CLLocationManagerDelegate>

@end

And in the code (.m) file – this code is to range beacons



@implementation glimbeaconViewController
{
    NSMutableDictionary *_beacons;
    CLLocationManager *_locationManager;
    NSMutableArray *_rangedRegions;
    CLBeaconRegion *_region;

}
...

- (void)viewDidLoad
{
    [super viewDidLoad];
    _locationManager = [[CLLocationManager alloc] init];
    _locationManager.delegate = self;
}

- (void) locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{

    if ([beacons count] > 0) {

        // Handle your found beacons here
        CLBeacon *beacon = [beacons objectAtIndex:0];
        NSString *_cnt = [[NSString alloc] initWithFormat:@"Number of beacons is : %lu and the first one is %f away from you",(unsigned long)[beacons count],beacon.accuracy];
        NSLog(_cnt);
    } else {
        NSLog(@"there are no beacons in range");
    }
}

-(void)viewDidAppear:(BOOL)animated
{
    NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:@"74278bda-b644-4520-8f0c-720eaf059935"];
    _region = [[CLBeaconRegion alloc] initWithProximityUUID:proximityUUID identifier:@"Glimworm iBeacon"];
    [_locationManager startRangingBeaconsInRegion:_region];

}
-(void) viewDidDisappear:(BOOL)animated
{
    [_locationManager stopRangingBeaconsInRegion:_region];

}

The code to detect is you are in region at all would be



-(void)viewDidAppear:(BOOL)animated
{
    NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:@"74278bda-b644-4520-8f0c-720eaf059935"];
    _region = [[CLBeaconRegion alloc] initWithProximityUUID:proximityUUID identifier:@"Glimworm iBeacon"];
    [_locationManager startMonitoringForRegion:_region];
}

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

- (void) locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
    switch (state) {
        case CLRegionStateInside:
            /* it would be smart to start ranging beacons here */
            break;
        case CLRegionStateOutside:
        case CLRegionStateUnknown:
        default:
            /* beacons will typically be on a low refresh */
            /* so they will probably flip flop a bit when you are in range */
            /* I would advise to stop ranging on a timer */
            NSLog(@"Region unknown");
    }
}