An overview of Core Bluetooth Framework

Apple introduced Core Bluetooth Framework with IOS 5 SDK. With the Core Bluetooth framework, developers can write an application that communicates with hardware gadgets and ios devices using Bluetooth Low Energy Standard.

In this article, we will see about Bluetooth low energy and an overview of the Core Bluetooth Framework.

What Is Bluetooth Low Energy?

Bluetooth Low Energy(BLE), sometimes referred to as Bluetooth Smart, is the technology for transferring data. It consumes low energy and allows the device battery to last longer. Ideally, BLE is used to transmit small packets of data, such as fitness-related data, to a fitness tracker.

Two major players are involved in all Bluetooth low-energy communication: Central and Peripheral.

Central And Peripherals In Core Bluetooth

Central

It defines the logic behind Core Bluetooth communication. It can scan, connect and disconnect peripherals and consumes information available at each peripheral. The central devices are usually mobile devices or tablets.

Peripheral

The device with information to share, e.g., Heart rate or temperature etc. The information can be pushed or advertised over the air. The peripheral devices are things like Heart rate monitors, BLE enables proximity tags, etc.

The following image defines the relationship between central and peripherals.

In the above scenario, IOS devices (Central) communicate with the Heart rate Monitoring system (Peripheral) to get heart rate information and show it on a device.

Jayu Rewards Is A BLE Based Next Generation Digital Rewards System

How Central Communicates With Peripherals?

In Bluetooth low energy, Advertising is the primary way peripherals make their presence known via BLE.

Peripherals broadcast some of the data they have in advertising packets. An advertising packet is a relatively small bundle of data that may contain useful information that peripheral offers, such as the peripheral’s name and other primary functionality. For example, a Heart rate monitor may advertise that it provides a Heartbeat per minute.

On the other hand, Central can scan and listen to any peripheral advertising device and connect to a particular device for more information that it’s interested in.

BLE peripheral is connected to Only one central at One time. As a peripheral connects to a central device, it will stop advertising itself, and other devices will no longer be able to see or connect to it until the existing connection is broken.

The Bluetooth low-energy devices transfer the data through Services and Characteristics.

Services And Characteristics In Bluetooth Low Energy

Services are the collection of data or characteristics. The device can contain multiple services. Each service distinguishes itself from other services by using a Unique Numeric Id called UUID, which can be either 16-bit or 128-bit.

Characteristics are like properties of the peripheral device, which provides more details about the services. the service can have more than one characteristic. Similar to the service characteristics also distinguishes itself using predefined 16-bit or 128-bit UUID.

CBPeripherals, CBCentralManager, CBServices, CBCharacteristics in Core Bluetooth Framework

In the core Bluetooth framework, peripherals are represented by the CBPeripheral object and services related to the peripheral device are represented by the CBService object.

CBCharacteristics objects are used to represent characteristics of peripheral services. Central is represented by the CBCentralManager object that manages discovered and connected peripherals.

The following figure shows the basic hierarchical structure of peripherals services and characteristics.

Now we have enough knowledge about core Bluetooth before we proceed, I will give you the basic workflow of core Bluetooth:–

1. First, Create an Object of CBCentralManager.

2. If the Central device state is PoweredOn, Scan for the peripheral device.

3. When you find a peripheral you want to connect to, stop scanning and then connect to the peripheral you found.

4. After the connection successfully discovers the peripheral services, you can discover a specific service or ask to return all services that the peripheral offers.

5. After you find the service you are interested in, discover its characteristics. The peripheral service may have one or more characteristics.

6. When you find the characteristic you are interested in, you can read from or Write the values to those characteristics.

Let’s create one project with a single view controller and add the Core Bluetooth Framework.

Import the corebluetooth framework in viewcontroller and confirm the delegate CBCentralManagerDelegate and CBPeripheralDelegate.

First, you must allocate and initialize a central manager instance before you can perform any Bluetooth low-energy transactions.

Create object of CBCentralManager and confirm delegates in viewDidLoad

var centralManager:CBCentralManager!

override func viewDidLoad() {

super.viewDidLoad()

// Do any additional setup after loading the view, typically from a nib.

centralManager = CBCentralManager()

centralManager = CBCentralManager(delegate: self, queue: dispatch_get_main_queue(), options:nil)

}

When you create a central manager, the central manager calls the centralManagerDidUpdateState: method of its delegate object. you must implement this delegate method to ensure that Bluetooth low energy is supported and available on the central device.

There are the following states of CBCentralManager:–

  • CBCentralManagerStateUnknown
  • CBCentralManagerStateResetting
  • CBCentralManagerStateUnsupported
  • CBCentralManagerStateUnauthorized
  • CBCentralManagerStatePoweredOff
  • CBCentralManagerStatePoweredOn

Implement the method to get the device state. As mentioned earlier central discovers and connects to peripherals that are advertising. You can discover any peripheral advertising device by calling scanForPeripheralsWithServices:options: method of CBCentralManager class. Like this :

print(“Scanning Started“)
centralManager.scanForPeripheralsWithServices(nil,options:[CBCentralManagerScanOptionAllowDuplicatesKey : false])

Hire BLE App Developers!

NOTE:

Here we pass nil for the first parameter; the central manager returns all discovered peripherals regardless of their supported services. instead of nil, you can pass an array of CBUUID objects, each representing the UUID of a service that is peripheral advertising.

After scanning is completed, the central manager calls the central manager: didDiscoverPeripheral:advertisementData:RSSI: method each time a peripheral is discovered. Each peripheral that is discovered is returned as CBPeripheral object.

func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {

print(“Discovered \(peripheral.name)  at  \(RSSI)”)

}

Stop scanning for other devices to save power when you find a peripheral.

centralManager.stopScan()

print(“Scanning Stopped“)

After you have discovered a peripheral device that is advertising services you are interested in, you can request a connection to the peripheral by calling the connectPeripheral:options: method. simply call this method and specify the discovered peripheral you want to connect to. Like this: –

central.connectPeripheral(peripheral, options: nil)

Assuming that your connection request is successful, the central manager calls the centralManager:didConnectPeripheral: method like:–

func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) {

         print(“Connected“)

}

and before you begin interacting with the peripheral, you should set the peripherals delegate to ensure that it receives the appropriate callback

peripheral.delegate = self

after you have established a connection to the peripheral, you can begin to explore its data. First, discover its available services. You can discover all services of peripheral by calling discoverSerices: method of CBPeripheral class like: –

peripheral.discoverServices(nil)

NOTE:

In the above method, you can pass an array of CBUUID of the services you are interested in to save battery life and unnecessary use of time.

When the specified services are discovered, the peripheral calls the peripheral:didDiscoverServices: method. It creates an array of CBService objects for each service discovered on the peripheral. Implement this delegate method to access the array of discovering services like:–

func peripheral(peripheral: CBPeripheral, didDiscoverServices error: NSError?) {

          for service in peripheral.services! {

                 print(“Discovered service: \(service)”)

                    ….

           }

          …..

}

after you find the service that you are interested in. The next step is to explore the service’s characteristics to discover all characteristics of the service simply call discoverCharacteristics:forservice: method of CBPeripheral class.

print(“Discovering characteristic for service: \(interestedservice)”)

peripheral.discoverCharacteristics(nil,forService: service)

NOTE:

Here we discover all characteristics of peripheral’s service. Because a peripheral’s service may contain many more characteristics than you are interested in, instead of discovering all of them, specify the UUIDs of the characteristic that you are interested in to save battery life and unnecessary use of time.

The peripheral calls peripheral:didDiscovercharacterisitcsForSerivce:error: method of its delegate object when a characteristic of the specified service is discovered. Core Bluetooth creates an array of CBCharacteristic objects, one for each characteristic that is discovered like this: –

func peripheral(peripheral: CBPeripheral, didDiscoverCharacteristicsForService service: CBService, error: NSError?) {

         if (error != nil) {

            print(“error: \(error?.localizedDescription)”)

               return

           }

       for characteristic in service.characteristics! {

           print(“Discovered characteristic: \(characteristic)”)

           ……

     }

    …..

}

Retrieving The Value Of A Characteristic

A characteristic contains a single value representing more information about a peripheral’s service. you can retrieve the value of a characteristic by reading it directly or subscribing to it.

After you have found a characteristic of the service that you are interested in, you can read the characteristic value by calling readValueForCharacteristic: method by specifying the appropriate characteristic.

print(“Reading value for characteristic: \(interestedcharacteristic)”)

peripheral.readValueForCharacteristic(interestedcharacteristic)

when you read a value of characteristic, the peripheral calls peripheral:didUpdateValueForCharacteristic:error: method to retrieve the value. If the value is successfully retrieved, you can access it through the characteristic value property like this: –

func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) {

     if (error != nil) {

                print(“Error:\(error?.localizedDescription)”)

                return

      }

    var data: NSData = characteristic.value

    // parse the retrieved data

    ……..

}

NOTE

All the characteristic values are not readable. You can determine whether a characteristic value is readable by accessing the CBCharacteristicPropertyRead constant. If you try to read a value that is not readable, the peripheral:didUpdateValueForCharacteristic:error method return a suitable error.

When you subscribe to a characteristic value, you receive a notification from the peripheral when the value changes.

You can subscribe to the value of a characteristic that you are interested in by calling the setNotifyValue:forcharacteristic: method of CBPeripheral class, set the value of the first parameter as true, like this: –

peripheral.setNotifyValue(true, forCharacteristic: interestedcharacteristic)
When you attempts to subscribe to characteristic value, the peripheral calls peripheral:didUpdateNotificationStateForCharacteristic:error: method if the subscription request fails, you can implement this method to get the actual cause of the error, like this: –
func peripheral(peripheral: CBPeripheral, didUpdateNotificationStateForCharacteristic characteristic: CBCharacteristic, error: NSError?) {

if ((error) != nil) {

print(“Error changing notification state \(error?.localizedDescription)”)

}

else {

print(“Notification began on: \(characteristic)”)

}

}

After successfully subscribing to a characteristic value, the peripheral notifies your app when the value has changed. each time the value changes, the peripheral calls the peripheral:didUpdateValueForcharacteristic:error: method, to retrieve the updated value, implement this method.

Writing The Value Of A Characteristic

If the characteristic value is writable, you can write its value with some data by calling the writeValue:forcharacteristic:type: method of CBPeripheral class like this:

print(“Writing value for characteristic: \(interestedcharacteristic)”)

peripheral.writeValue(data, forCharacteristic: interestedcharacteristic, type: .WithResponse)

When attempting to write the value of a characteristic, specify the type of writing you want to perform. In the above example, the write type is specified as CBCharacteristicWriteWithResponse, which indicates the peripheral let your app know whether the write is successful.

If you specified CBCharacteristicWriteType as CBCharacteristicWriteWithResponse the peripheral responds to your write request by calling peripheral:didWriteValueForCharacteristic:error: method.

func peripheral(peripheral: CBPeripheral, didWriteValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) {

if ((error) != nil) {

print(“Error Writing characteristic value \(error?.localizedDescription)”)

}

}
coma

Conclusion

You can also refer to a BLE-IOS-Data-Exchange project for more details.

After reading this tutorial, you should understand the core Bluetooth framework specifications and how you can use this to connect with low-energy peripheral devices to retrieve certain attributes related to the device.

Keep Reading

Keep Reading

Struggling with EHR integration? Learn about next-gen solutions in our upcoming webinar on Mar 6, at 11 AM EST.

Register Now

Let's create something together!