Hello world
In time-honored tradition, we can't conclude the first chapter without the traditional "Hello World" tutorial. We'll be using your Mac as an iBeacon broadcaster using the companion app, and the app will simply show an alert every time it enters or exits the region.
We will cover all of these concepts in more detail in later chapters, but for reference, here are the classes we'll be using:
CLLocationManager
: TheCLLocationManager
class delivers location-related events to your app and tells you when you enter or exit a regionCLLocationManagerDelegate
: TheCLLocationManagerDelegate
protocol defines the delegate methods used to receive location and heading updates fromCLLocationManager
CLBeaconRegion
: ACLBeaconRegion
object defines a type of region that is based on the device's proximity to a Bluetooth beacon
Let's get started
Fire up Xcode and start a new project. Choose Single View Application from the iOS template menu as your project type.
A new project dialog
Set up your new project using the values shown in the following screenshot:
A new project options dialog
Adding the Core Location framework
All of the features we need for this app to work are present in the Core Location framework.
Click on the project in the project navigator and scroll down to the Linked Frameworks and Libraries section of the General tab and then click on the add icon. We'll need to add the CoreLocation
framework as shown in the following screenshot:
Adding the Core Location framework
We only really care about the LIViewController
class for this tutorial as that's where we're going to be presenting to the user when we're moving in and out of regions. In order to do this, we need to add a reference to CoreLocation
. Open LIViewController.h
and add the following line just below the existing UIKit
import:
#import <CoreLocation/CoreLocation.h>
Tip
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
Adding a permission message
Since iOS 8.0, you must specify a location description message in your plist settings. This is a nice friendly message for the users to help them understand why they need permission to use those location services. To do this, open the project file, click on your target Hello World, and then under the Info tab, add a new item to the dictionary under Custom iOS Target Properties with the following values:
- Key:
NSLocationAlwaysUsageDescription
- Value:
This app needs your location to show you how cool iBeacon is.
Configuring the CLLocationManagerDelegate method
Our ViewController
instance is where all the action happens, so it makes sense for ViewController
to be aware of location events. For that, we need to make it CLLocationManagerDelegate
.
Go ahead and add the declaration to the LIViewController
interface declaration. Change the interface declaration in LIViewController.h
so that it looks like the following code:
@interface LIViewController : UIViewController<CLLocationManagerDelegate>
We also need to implement the CLLocationManagerDelegate
methods so that we can show our notification when the device enters a region. Add the following code to the end of the LIViewController
implementation in the LIViewController.m
file:
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region { UIAlertView * av = [[UIAlertView alloc] init]; av.title = [NSString stringWithFormat:@"Entered Region '%@'", region.identifier]; [av addButtonWithTitle:@"OK"]; [av show]; } -(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region { UIAlertView * av = [[UIAlertView alloc] init]; av.title = [NSString stringWithFormat:@"Left Region '%@'", region.identifier]; [av addButtonWithTitle:@"OK"]; [av show]; }
Tip
"Wait, what's CLRegion
?" I hear you asking. Well, CLBeaconRegion
inherits CLRegion
and so CLBeaconRegion
is CLRegion
. Remember that CLLocationManager
is used to deliver location-related events, which don't necessarily need to come from a beacon-related activity.
Adding a CLLocationManager instance
Now, our view controller will be notified when a CLLocationManager
instance receives events, but we don't have an instance of CLLocationManager
yet. Add the following property to the LIViewController
interface inside LIViewController.m
:
@property (nonatomic, strong) CLLocationManager * locationManager;
Preparing UUID
For our app to know which region it's looking out for, we need some way of storing the UUID. Add the following line just below the implementation in LIViewController.m
:
static NSString * uuid = @"EB9AB493-32C2-4E5C-BF67-76E86E338BB9";
Start monitoring
Our app is already ready to start accepting location-based updates. All we need to do now is create a region, instantiate our location manager, and start monitoring our regions. Overwrite the viewDidLoad
method of our LIViewController
with the following code. We'll go through the most important code shortly.
- (void)viewDidLoad { [super viewDidLoad]; NSUUID * regionUUID = [[NSUUID alloc] initWithUUIDString:uuid]; CLBeaconRegion * region = [[CLBeaconRegion alloc] initWithProximityUUID:regionUUID identifier:@"My Region"]; [region setNotifyOnEntry:YES]; [region setNotifyOnExit:YES]; self.locationManager = [[CLLocationManager alloc] init]; self.locationManager.delegate = self; [self.locationManager requestAlwaysAuthorization]; [self.locationManager startMonitoringForRegion:region]; }
Line by line
Let's break the preceding code down line by line:
- First, we create an
NSUUID
instance using our string identifier (uuid
) sinceCLBeaconRegion
requires an object of this type in order to be initialized:NSUUID * regionUUID = [[NSUUID alloc] initWithUUIDString:uuid];
- Next, we create a new
CLBeaconRegion
passing in ourNSUUID
:CLBeaconRegion * region = [[CLBeaconRegion alloc] initWithProximityUUID:regionUUID identifier:@"My Region"];
- Next, we configure our region events. We're interested in being notified when we enter and leave the region:
[region setNotifyOnEntry:YES]; [region setNotifyOnExit:YES];
- Next, we instantiate
CLLocationManager
and addViewController
as its delegate:self.locationManager = [[CLLocationManager alloc] init]; self.locationManager.delegate = self;
- Finally, we request permission for location services, then start monitoring for the
CLBeaconRegion
we've just created:[self.locationManager requestAlwaysAuthorization]; [self.locationManager startMonitoringForRegion:region];