Here at Calvium we have recently been working with iBeacons in iOS. (If you don’t know about iBeacon’s yet then have a read of our low down on iBeacons blog). We’ve found a lot of contradictory information on the Internet regarding how iOS 7.0 and iOS 7.1 is operated with regards to beacons, so we thought we would post what has worked for us.
Starting
- Add the CoreLocation framework to your project
- At the top of your view controller file
#import <CoreLocation/CoreLocation.h>
- Implement the
<CLLocationManagerDelegate>
delegate:
-(void)locationManager:(CLLocationManager *)manager
didEnterRegion:(CLRegion *)region {
NSLog(@"entered region");
}
-(void)locationManager:(CLLocationManager *)manager
didExitRegion:(CLRegion *)region {
NSLog(@"exited region");
}
- (void) locationManager:(CLLocationManager *)manager
didRangeBeacons:(NSArray *)beacons
inRegion:(CLBeaconRegion *)region {
NSLog(@"found %lu beacons", (long)[beacons count]);
}
- In the
viewDidLoad
function make a location manager
CLLocationManager *locationManager =
[[CLLocationManager alloc] init];
locationManager.delegate = self;
- Under the location manager set up a region – we’re just going to be regioning for default Estimote beacons.
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc]
initWithProximityUUID:[[NSUUID alloc]
initWithUUIDString:@"B9407F30-F5F8-466E-AFF9-25556B57FE6D"]
identifier:@"estimoteRegion"];
beaconRegion.notifyEntryStateOnDisplay = YES;
beaconRegion.notifyOnEntry = YES;
beaconRegion.notifyOnExit = YES;
- Start monitoring a region – this gives you notifications when you enter and exit a region
[locationManager startMonitoringForRegion:beaconRegion];
- Start ranging – this scans for beacons every 1 second.
[locationManager startRangingBeaconsInRegion:beaconRegion];
- Run your application on an actual iDevice which is iBeacon compatable running 7.1 or greater.
Notes:
We found that it was possible to find iBeacons by doing the following;- starting the app – start the region monitoring and beacon ranging – and be able to range 2 or 3 iBeacons without the didEnterRegion method being called.
This is why we decided to range for beacons, even if the app doesn’t think we’re in a region. The only side effect of this is the constant hollowed out notification icon in the status bar. Users can investigate this by this by going to Settings – Privacy – Location Services – and scrolling to the bottom of the page informs any inquisitive user about geofences.
We’re finding that this is becoming the norm with more apps that are making use of iBeacon technology.
Waking up a device with an iBeacon
iOS 7.1 included an update to iBeacon support in that previously, it took up to 30 minutes for a device to range for an iBeacon if the device was off, now this is pretty much instant.
1. Implement all the things mentioned in “Starting” into your App Delegate
- Change the “didEnterRegion” function to send a notification
-(void)locationManager:(CLLocationManager *)manager
didEnterRegion:(CLRegion *)region {
{
UILocalNotification *notification =
[[UILocalNotification alloc] init];
notification.alertBody = [NSString stringWithFormat:
@"You have entered the region"];
//show the notification
[[UIApplication sharedApplication]
presentLocalNotificationNow:notification];
}
- Implement a function to deal with showing a notification if the user already has the app open
- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification
{
NSString *cancelButtonTitle = NSLocalizedString(
@"OK",
@"Title for cancel button in local notification");
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:notification.alertBody
message:nil
delegate:nil
cancelButtonTitle:cancelButtonTitle
otherButtonTitles:nil];
[alert show];
}
We hope you find this blog useful. If you’re experimenting with iBeacons, do get in touch and let us know what you’re up to by following us at @Calvium on Twitter or commenting below.