Core Bluetooth (BLE)- Swift
Core Bluetooth is an iOS Framework provided by Apple to build Bluetooth Low Energy applications that communicate with hardware gadgets.
Core Bluetooth has several features.
- Setting up an iOS device as BLE central or peripheral.
- Handling low-level connection parameters.
- Transferring data between BLE devices.
- Error handling.
We will start by looking at Core Bluetooth concepts and how it communicates with hardware such as connection, read, write data. Before diving into XCode, lets overview quickly how the framework works. So it has 2 main players: Central and Peripheral (physical device).
Central:
Briefly, it defines logic behind Core Bluetooth communication, for the scan, connect, disconnect peripherals receiving information from the available device.
Peripheral (Bluetooth gadget):
Devices that share information through advertising over the air e.g temperature, battery level, etc.
The below figure illustrates the communication workflow between Central and Peripheral.
CoreBluetooth main classes & Protocol
CBCentralManager & CBCentralManagerDelegate
Are responsible to check that Bluetooth is ON and then to scan, discover, connect, and manage peripherals.
CBPeripheral & CBPeripheralDelegate
Represents physical BLE devices as they were discovered by CBCentralManager. They are identified by UUID (universally unique identifier) which contains one or more services.
CBService
Represents service physical BLE device, and provide data associated behaviors and characteristics given BLE-device.
CBCharacteristics
Represent the data of the device’s service and contains a single value. Here is where we can read, write, and subscribe to the data from the device (ex: battery level, temperature, LED light).
I’m using “Thunderboard Sense 2” from the Silicon Labs you can check for more details link below.
Let’s see it in Practice
Setup XCode
After creating a project first we need to ask permission from the user. In Info.plist file we are going to add “NSBluetoothAlwaysUsageDescription”
Now we can open our ViewController and import CoreBluetooth variable type CBCentralManager.
Implement delegates CBCentralManager
Now we have an instance of CBCentralManager we can implement centralManagerDidUpdateState delegates methods in order get notified Bluetooth has powered on, and then we can start scanning peripherals, by calling .scanForPeripherals.
Next, we need another delegate method didDiscoverPeripheral, when it finds peripheral BLE-device we can connect and store a copy of it.
Since I know my BLE-Device name (“Thunder Sense #33549”) I can find it and connect to it, another option would be using UUID.
Note: You can find the name of your BLE-Device from the guidebook, or documentation of your device, in case you didn’t find the name just print the name of peripherals on the console.
Another step from the CBCentralManagerDelegate method we need is didConnect peripheral and call peripheral.discoverServices and next, we need to implement CBPeripheralDelegate methods.
in discoverServices if you pass Nil it’s going to discover all services but if you know specific service you can discover only that.
Here I’m looking only for AutomationIO which I found from the SiliconLab GitHub source project. https://github.com/SiliconLabs/thunderboard-ios/blob/master/ThunderBoard/CBUUIDExtensions.swift
Note: You can find your services, characteristics BLE from your device documentation.
let AutomationIO = CBUUID(string: “0x1815”)
peripheral.discoverServices([AutomationIO])
Implement delegates CBPeripheralDelegate & Discover Service, Characteristics
So the first thing we need is didDiscoverServices and then to discover characteristics by calling peripheral.discoverCharacteristics(nil, for: service) “again here bypassing nil it's going to discover all characteristics.”
Next, we need to implement didDiscoverCharacteristicsFor method coming from the CBPeripheral delegate for getting characteristics. We’re interested only in Digital characteristics.
let Digital = CBUUID(string: “0x2A56”)
Write data to Characteristic
So, we’ve connected to a peripheral and discovered service drilled down into characteristics, now are going to look at writing value to characteristic on the peripheral. To write peripheral, we’re going to send a data instance that represents data we’re trying to store on peripheral.
Well, the final step we need a UISwitch on ViewController for the turn on/of light, then to call peripheral.writeValue for the write data to characteristic.
On peripheral.writeValue we are passing Data which means we need to convert other types to Data,
Finally, let see the result
WrapUp
The main idea of this article was to give you an introduction to how the CoreBluetooth works. if you want to learn more, please visit the Core Bluetooth: https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/AboutCoreBluetooth/Introduction.html
I also recommend you to check WWDC 2019 What’s new in CoreBluetooth:https://developer.apple.com/videos/play/wwdc2019/901/
The source code: https://github.com/AminPlusPlus/BLE-SiliconLab
Thank reading!