The Core Bluetooth (CB) framework provides the necessary resources for iOS apps to communicate with devices that are equipped with Bluetooth Low Energy technology (BTLE). This tutorial will guide you through the evolution of CB from iOS 5 to iOS 7. Additionally, you will learn how to configure a Core Bluetooth central and peripheral, how to communicate between them, and some best programming practices.
Introduction
The Core Bluetooth tutorials are divided into two sections. The first one covers the theoretical aspect of Core Bluetooth, while the second serves as a complete practical lesson. Here you will find the complete source code for the practical tutorial, plus an additional starting project.
1. Background
BTLE is based on the Bluetooth 4.0 specification, which among other things, defines a set of protocols for communicating between low energy devices. In BTLE there are two profiles:
- The central: typically defines the logic behind a CB communication. It is able to scan, connect, and disconnect peripherals. Plus, it consumes the information available at each peripheral.
- Peripheral: a device that has important information to share (heart rate, temperature, etc). The information can be pushed or advertised over the air.
The following image shows a central and a peripheral device:
Each “profile” represents an equivalent iOS object, namely the CBCentralManager
and the CBPeripheral
.
As stated earlier, the CBCentralManager
manages discovered or connected remote peripheral devices (CBPeripheral
). As soon as the CBCentralManager
connects to a peripheral, interaction with its data begins. Data stored in peripherals are organized in a hierarchical tree based on its services and characteristics.
These services can be Alert Notification Service
, Blood Pressure
, Heart Rate
, etc. The official list of GATT
services specifications can be found on this page.
The characteristic of a service in practice is the service value. In this tutorial, the Blood Pressure
service is the blood pressure value at a specific moment. The next figure illustrates a custom peripheral with one service and two characteristics.
In Core Bluetooth, the services of a remote peripheral are represented by CBService
objects. Similarly, the characteristics of a remote peripherals service are represented by CBCharacteristic
objects. The next figure illustrates the hierarchical structure of a CBService
peripheral.
A given peripheral can have multiple services and multiple characteristics for each service. There is not a specific limit number for each one.
Note that you should read and learn the official Core Bluetooth Framework Reference to achieve a complete understanding of this technology.
2. Core Bluetooth Evolution
The Core Bluetooth Framework appeared in iOS 5 and introduced a new way to communicate between devices using Bluetooth wireless technology. During each iOS release, Apple improves and adds new features to Core Bluetooth.
In iOS 5, the main Core Bluetooth features were the CBCentralManager
, CBPeripheral
, Central, Client, and Observer. In this version only two classes existed, the CBCentralManager
and CBPeripheral
. The first class was designed to discover and connect to several (limited) peripherals. The second class was responsible for the visualization of a device and created a mechanism that enabled the Central to access data available on remote services.
In iOS 6, Apple introduced several Core Bluetooth features and improvements including CBPeripheralManager
, Peripheral Database Caching, Broadcaster, Peripheral, and Server. The principal feature was the Server
role. It permitted developers to create and specify custom services. In addition, the CBPeripheralManager
introduced a customized way to create services and mechanisms that define how information is advertised to the network. Additionally, peripheral database caching greatly improved the general Bluetooth performance (especially in the discovery phase).
After a few years of gathering feedback, Apple refined the Bluetooth framework in iOS 7 with the following features:
- Simpler device management
- Smarter peripherals
- Performance improvements
- Application persistence
- Built-in services
- State preservation and restoration
- Database caching evolved and now supports services, characteristics, and descriptors (previously only stored services and characteristics).
- For sending data, the amount of data transmitted also changed. It is now possible to support MTU exchange requests and change the maximum amount of data per PDU.
- iBeacon is a technology that permits the users to check the location and proximity of a specific device and the user’s iOS device.
- Apple notification center service (ANCS) is an Apple-specific GATT service that exposes the characteristics necessary for accessories to be alerted for any notification events on the iOS device (notifications arriving, being modified, or dismissed) and to get more information about those events. Through this service, external accessory developers have full access to device events. However, the current version supports reading notification data only.
If you want to start playing with BTLE development, you must bear in mind the following considerations:
- Note that Apple is decreasing iOS simulator support for Core Bluetooth. Thus, the best way to test your code is to run it directly on a iOS device.
- You need an iOS device with hardware support for Bluetooth 4.0. All devices released since the iPhone 4S (including the 4S) support Bluetooth 4.0.
- Your app can talk to a BTLE peripheral (this can be a second iOS device or a Mac).
3. CB Background Processing
Defining how an app reacts to a background or foreground state is crucial. Every app must behave differently in both background and foreground because system resources are limited. By default, many of the common CB tasks (on both the central and peripheral) are disabled while your app is in the background or in a suspended state. However, you can declare your app to support the Core Bluetooth background execution modes to allow it to be woken up from a suspended state to process certain events.
Note that even if your app supports one or both of the CB background execution modes, it cannot run forever. At a given point, the system may need to terminate your app to free up memory for the current foreground app because iOS is sovereign in memory management. Notwithstanding, Core Bluetooth supports saving state information for central and peripheral manager objects and restoring that state at app launch time.
If your app does not support background activities, all Bluetooth events that occur when the app is in a suspended state are queued by the system and fired to the app when it comes to foreground state. These alerts can be defined when calling the connectPeripheral:options:
method of the CBCentralManager
class when a connection to peripheral is made. There are three types of alerts:
CBConnectPeripheralOptionNotifyOnConnectionKey
when you want the system to display an alert for a given peripheral if the app is suspended when a successful connection is made.CBConnectPeripheralOptionNotifyOnDisconnectionKey
when you want the system to display a disconnection alert for a given peripheral if the app is suspended at the time of the disconnection.CBConnectPeripheralOptionNotifyOnNotificationKey
when you want the system to display an alert for all notifications received from a given peripheral if the app is suspended at the time.
On the other hand, if your application supports the background mode you need to declare it (UIBackgroundModes
) in the property list (Info.plist) file. When your app declares it, the system wakes it up from a suspended state to allow it to handle Bluetooth events. This support is important for apps that interact with Bluetooth Low Energy devices that deliver data at regular intervals, such as a heart rate monitor. There are two background roles: one for central devices and one for peripherals.
4. Best Practices for a CBCentralManager
Despite the fact that the Core Bluetooth framework makes many of the central transactions transparent to your app, there are several options that you must consider when developing a Bluetooth app. Since you are dealing with Low Energy devices, you should remember that every operation drains energy from your Bluetooth device.
Therefore, you must take into consideration the following:
- Device scanning: you should only scan for new devices when absolutely necessary. Minimizing radio usage is especially important when developing an iOS device because radio usage has an adverse effect on any iOS device battery life.
- Multiple advertisements from the same device: remote peripheral devices may send out multiple advertising packets per second to announce their presence to listening centrals. Thus, you can use the
scanForPeripheralsWithServices:options:
method to prevent this so all advertisements from a specific device are treated as one. However, you can use theCBCentralManagerScanOptionAllowDuplicatesKey
option if you want to receive multiple advertisements from the same device. - Extract the peripheral’s data wisely. A peripheral device may have many services and characteristics than you are interested in. You should look for and discover only the services and characteristics your app needs.
- Subscribe or check the characteristics values. You can retrieve characteristics by using user input or doing so automatically when that characteristic changes. You should use one method accordingly.
- Every time you know that a connection is not needed you should terminate it. Due to caching mechanisms you can quickly re-connect. Apple has a specific work flow when a central tries to reconnect to a device. The next image demonstrates that work flow:
5. Best Practices for a CBPeripheral
Similar to the CBCentralManager
role, the CBPeripheral
has some practices that should be followed in order to create an efficient Bluetooth app.
With regards to advertising, remember that when your app is in the foreground it can use up to 28 bytes of space in the initial advertisement data. Be aware that you should only advertise data that really matters, not only for performance issues but to keep the channel clean. Also, you should offer the user a way to advertise as desired, so that the user has a way to control the advertisement’s frequency.
Also when you configure your characteristics, you should enable them to support notifications. To achieve this, you must add the CBAttributePermissionsReadable
property to the permissions
in the CBMutableCharacteristic
object.
Be aware that since Bluetooth is an emerging technology, more and more devices use it and try to sniff the network to access “free” data. Because of this, you should always require a paired connection to access the sensitive data of your peripheral.
Conclusion
After reading this tutorial, you should understand the Core Bluetooth framework specifications. In the next tutorial, you will learn how to program a CBCentralManager
and CBPeripheral
.
If you have any questions or comments, please leave them below!