iBeacon Tutorial with iOS and Swift

Learn how you can find an iBeacon around you, determine its proximity, and send notifications when it moves away from you. By Owen L Brown.

Leave a rating/review
Save for later
Share

Have you ever wished that your phone could show your location inside a large building like a shopping mall or baseball stadium?

Sure, GPS can give you an idea of which side of the building you are in. But good luck getting an accurate GPS signal in one of those steel and concrete sarcophaguses. What you need is something inside of the building to let your device determine its physical location.

Enter iBeacons! In this iBeacons tutorial you’ll create an app that lets you register known iBeacon emitters and tells you when your phone has moved outside of their range. The use case for this app is attaching an iBeacon emitter to your laptop bag, purse, or even your cat’s collar — anything important you don’t want to lose. Once your device moves outside the range of the emitter, your app detects this and notifies you.

To continue with this tutorial, you’ll need to test on a real iOS device and an iBeacon. If you don’t have an iBeacon but have a second iOS device, you might be able to use it as a beacon; read on!

Getting Started

There are many iBeacon devices available; a quick Google search should help reveal them to you. But when Apple introduced iBeacon, they also announced that any compatible iOS device could act as an iBeacon. The list currently includes the following devices:

  • iPhone 4s or later
  • 3rd generation iPad or later
  • iPad Mini or later
  • 5th generation iPod touch or later

Note: If you do not have a standalone iBeacon emitter but you do have another iOS device that supports iBeacons, you can follow along by creating an app that acts as an iBeacon as described in Chapter 22 — What’s new in Core Location of iOS 7 by Tutorials.

An iBeacon is nothing more than a Bluetooth Low Energy device that advertises information in a specific structure. Those specifics are beyond the scope of this tutorial, but the important thing to understand is that iOS can monitor for iBeacons that emit three values known as: UUID, major and minor.

UUID is an acronym for universally unique identifier, which is a 128-bit value that’s usually shown as a hex string like this: B558CBDA-4472-4211-A350-FF1196FFE8C8. In the context of iBeacons, a UUID is generally used to represent your top-level identity.

Major and minor values provide a little more granularity on top of the UUID. These values are simply 16 bit unsigned integers that identify each individual iBeacon, even ones with the same UUID.

For instance, if you owned multiple department stores you might have all of your iBeacons emit the same UUID, but each store would have its own major value, and each department within that store would have its own minor value. Your app could then respond to an iBeacon located in the shoe department of your Miami, Florida store.

ForgetMeNot Starter Project

Download the starter project here — it contains a simple interface for adding and removing items from a table view. Each item in the table view represents a single iBeacon emitter, which in the real world translates to an item that you don’t want to leave behind.

Build and run the app; you’ll see an empty list, devoid of items. Press the + button at the top right to add a new item as shown in the screenshot below:

First Launch

iBeacon

To add an item, you simply enter a name for the item and the values corresponding to its iBeacon. You can find your iBeacon’s UUID by reviewing your iBeacon’s documentation – try adding it now, or use some placeholder values, as shown below:

Add an Item

iBeacon

Press Save to return to the list of items; you’ll see your item with a location of Unknown, as shown below:

List of Items Added

iBeacon

You can add more items if you wish, or swipe to delete existing ones. UserDefaults persists the items in the list so that they’re available when the user re-launches the app.

On the surface it appears there’s not much going on; most of the fun stuff is under the hood. The unique aspect in this app is the Item model class which represents the items in the list.

Open Item.swift and have a look at it in Xcode. The model class mirrors what the interface requests from the user, and it conforms to NSCoding so that it can be serialized and deserialized to disk for persistence.

Now take a look at AddItemViewController.swift. This is the controller for adding a new item. It’s a simple UIViewController, except that it does some validation on user input to ensure that the user enters valid names and UUIDs.

The Add button at the bottom left becomes tappable as soon as txtName and txtUUID are both valid.

Now that you’re acquainted with the starter project, you can move on to implementing the iBeacon bits into your project!

Core Location Permissions

Your device won’t listen for your iBeacon automatically — you have to tell it to do this first. The CLBeaconRegion class represents an iBeacon; the CL class prefix indicates that it is part of the Core Location framework.

It may seem strange for an iBeacon to be related to Core Location since it’s a Bluetooth device, but consider that iBeacons provide micro-location awareness while GPS provides macro-location awareness. You would leverage the Core Bluetooth framework for iBeacons when programming an iOS device to act as an iBeacon, but when monitoring for iBeacons you only need to work with Core Location.

Your first order of business is to adapt the Item model for CLBeaconRegion.

Open Item.swift and add the following import to the top of the file:

import CoreLocation

Next, change the majorValue and minorValue definitions as well as the initializer as follows:

let majorValue: CLBeaconMajorValue
let minorValue: CLBeaconMinorValue

init(name: String, icon: Int, uuid: UUID, majorValue: Int, minorValue: Int) {
  self.name = name
  self.icon = icon
  self.uuid = uuid
  self.majorValue = CLBeaconMajorValue(majorValue)
  self.minorValue = CLBeaconMinorValue(minorValue)
}

CLBeaconMajorValue and CLBeaconMinorValue are both a typealias for UInt16, and are used for representing major and minor values in the CoreLocation framework.

Although the underlying data type is the same, this improves readability of the model and adds type safety so you don’t mix up major and minor values.

Open ItemsViewController.swift, add the Core Location import to the top of the file:

import CoreLocation

Add the following property to the ItemsViewController class:

let locationManager = CLLocationManager()

You’ll use this CLLocationManager instance as your entry point into Core Location.

Next, replace viewDidLoad() with the following:

override func viewDidLoad() {
  super.viewDidLoad()

  locationManager.requestAlwaysAuthorization()

  loadItems()
}

The call to requestAlwaysAuthorization() will prompt the user for access to location services if they haven’t granted it already. Always and When in Use are variants on location permissions. When the user grants Always authorization to the app, the app can start any of the available location services while it is running in the foreground or background.

The point of this app is to monitor for iBeacon regions at all times, so you’ll need the Always location permissions scope for triggering region events while the app is both in the foreground and background.

iOS requires that you set up a string value in Info.plist that will be displayed to the user when access to their location is required by the app. If you don’t set this up, location services won’t work at all — you don’t even get a warning!

Open Info.plist and add a new entry by clicking on the + that appears when you select the Information Property List row.

iBeacon

Fortunately, the key you need to add is in the pre-defined list shown in the dropdown list of keys — just scroll down to the Privacy section. Select the key Privacy – Location Always Usage Description and make sure the Type is set to String. Then add the phrase you want to show to the user to tell them why you need location services on, for example: “ForgetMeNot needs to know where you are”.

iBeacon

Build and run your app; once running, you should be shown a message asking you to allow the app access to your location:

Allowing access to your location

iBeacon

Select ‘Allow’, and the app will be able to track your iBeacons.