Play with advanced BLE


Bluetooth Low Energy or BLE has become very popular now a days as it is widely used in personal fitness gadgets, home automation products etc. Although BLE is similar to classic Bluetooth, its power consumption is less. Almost all major operating systems natively support BLE such as iOS 5 and later, Windows Phone 8.1, Android 4.3 and later, BlackBerry 10.

This article is limited to BLE in IOS and how it is implemented in it. While the sections to follow provide the necessary information with code fragments, it is suggested to download the sample project to get a complete picture. Please note that sample project works on IOS 7 or later and has basic functionality such as scanning and connecting to the BLE devices.

The Core Bluetooth framework is an abstraction of the Bluetooth low energy protocol stack and provides the necessary means for the developers to create apps that interact with the Bluetooth low energy devices. Using this framework, an app discover, explore, and interact with low energy peripheral devices.

Internals of Core Bluetooth two major components play a vital role in the framework:

  • Central:   Consumes the data provided by a peripheral, which in turn can be used to perform an action.
  • Peripheral: Holds the data that is needed by other devices. They make their presence known by advertising the data they have over the air.


Central has the capability to scan for peripherals and can request for a connection when a peripheral is discovered. Upon connecting Central can do further interaction and use the peripheral’s data. Scanning for peripherals can be performed on the basis of the app requirements.


  • Below code initiates the peripheral scanning and can find any BLE signal broadcasting peripheral.
[self.cbCentralManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey: @NO}];

Below code fragment can be used to scan for peripherals with services, where scanning can be done for a single or set of services.

NSArray *services = @[[CBUUID UUIDWithString:@"any services of your choice"]];
[self.cbCentralManager scanForPeripheralsWithServices:services options:@{CBCentralManagerScanOptionAllowDuplicatesKey:  @NO}];
  • There could be a requirement where scanning for peripherals may have to be done continuously. For this purpose a timer object can be used, where the desired interval in seconds can be specified.
self.scanTimer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(scanComplete) userInfo:nil repeats:NO];
  • A delegate method is invoked whenever a peripheral is located. Further filtering of the peripheral can be done here such as check for the Peripheral property etc. and communicate with it only if such property is found on the peripheral.
(void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData

There could be a scenario where large number of BLE devices exist and a faster way of identifying all the scanned peripherals. In such case a DICTIONARY or ARRAY can be used to store all the scanned peripherals with peripheral identifier as Key. These can be used later to quickly connect to a BLE peripheral.

  • It is a good practice to stop the scanning when the desired peripherals are found, which can be done with the below line of code:
[self.cbCentralManager stopScan];

Note: iOS 7 used to support the scanning even if the device central manager power is OFF. In iOS 8 this behavior is changed and the device central manager will not scan until the power is ON.

The delegate method for this is as follows:

(void)centralManagerDidUpdateState:(CBCentralManager *)central
    if ([central state] == CBCentralManagerStatePoweredOff) {
        NSLog(@"BLE hardware is powered off");
    else if ([central state] == CBCentralManagerStatePoweredOn) {
         NSLog(@"BLE hardware is powered on and ready");
    else if ([central state] == CBCentralManagerStateUnauthorized) {
          NSLog(@"BLE state is unauthorized");
    else if ([central state] == CBCentralManagerStateUnknown) {
          NSLog(@"BLE state is unknown");
    else if ([central state] == CBCentralManagerStateUnsupported) {
         NSLog(@"BLE hardware is unsupported on this platform");

Start searching when the central manager is power ON.

Peripheral Communication App can connect to a peripheral as soon as it is located, which can be done with:

[self. cbCentralManager connectPeripheral:peripheral options:nil];

If a list of peripherals are available then the connection can be made with the help of peripheral identifier. This is very useful when there are many peripherals.

NSString *identifier=[NSString stringWithFormat:@"%@", [[peripheral identifier] UUIDString]];NSUUID *id=[[NSUUID alloc]initWithUUIDString:identifier];
if (id) {
          NSArray *peripherals=[self.cbCentralManager retrievePeripheralsWithIdentifiers:@[id]];
          if ([peripherals count]>0)
            CBPeripheral *peripheral=[peripherals objectAtIndex:0];
            [self.cbCentralManager connectPeripheral:peripheral options:nil];

Below delegates will be fired upon successful connection.

(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral

If the connection results in failure, below delegate is fired:

(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error

It is a good practice to dis-connect the peripheral when it is no longer needed, which can be accomplished with the below line:

[self.cbCentralManager cancelPeripheralConnection:peripheral];

Upon disconnection below delegate is fired

(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error

We will explore more about Next peripherals, services and characteristics in the coming articles

You can download the sample project from here

Are you interested? follow us and get notified of new posts

Leave A Reply

12 + twelve =