Mastering the fundamentals of BLE for iOS using Swift.

Аλέξιος
4 min readSep 12, 2021

--

Picture 1— The BLE connection diagram by Martin Shellaker, director at SMP.

From the first impression of working with BLE (Bluetooth Low Energy), I was surprised by how the event-based buses work. By the way, from my experience in Embedded Software Development, I was a neophyte and circumvented the convoluted challenging tasks that were arduous and arcane for me.

Nevertheless, that day has come and now I am going to elucidate the pith of BLE internals from the perspectives of iOS and using the Swift programming language.

First of all, here is the reference diagram for the BLE functioning logic.

Picture 2 — The BLE connection workflow diagram by @amin030296.

Here are the hints for each step of the BLE connection to clarify this scheme that makes it more candid.

  • Firstly, the Bluetooth connection always begins with initialization when the user permits the connection during the application launch. So, if the peripheral is enabled for discovery, then it sends the broadcasting packets to the phone for identification. [1]
  • Secondly, when the advertisement packet is received by phone from the source, the Bluetooth manager stops scanning and attempts to connect to the sender. [2]
  • Thirdly, if the binding between the mobile device and peripheral is successful, the phone continues discovering available services on peripheral while the peripheral halts sending advertisement packets on connection and then provides the information about the accessible services. [3]
  • Next, the central manager requests the peripheral for the additional characteristics, while the peripheral responds with further information.[4]
  • Ultimately, the BLE connection between two gadgets is established! Now, let us see how to implement this in Xcode!

At first, it is mandatory to import the CoreBluetooth framework to use the mandatory functions for establishing BLE connections. Additionally, define the class with the name conforming to CBCentralManagerDelegate” and “CBPeripheralDelegate” protocols.

Also, write the description of the peripheral’s UUID service which was received from broadcasting packets. By the way, assign the variables to the central Bluetooth manager and peripheral matching their types.

let DEVICE_SERVICE_UUID = CBUUID.init(string: "b4250400-fb4b-4746-b2b0-93f0e61122c6"); //the peripheral's UUIDvar centralManager: CBCentralManager!;    
var peripheral: CBPeripheral!;

Besides, the CBCentralManagerDelegate” requires only one method for handling updates occurring on the phone’s Bluetooth central manager, if the user grants access to the application during its startup or in the iOS settings for exploring the BLE peripherals with specified UUID. This is the first step [1] from the BLE connection procedure diagram description.

func centralManagerDidUpdateState(_ central: CBCentralManager)

Furthermore, if the phone locates the BLE device, the “didDiscover peripheral” method will manage the future events on discovery. It usually happens when the iOS gadget collects the advertisement package from the peripheral. This is step two [2] from the BLE connection procedure diagram description.

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber)

Consequently, if the central manager establishes the connection with the BLE peripheral, it looks for additional services available on the peripheral. The “didConnect peripheral” method will take care of future events regarding the network state. This is step three [3] from the BLE connection procedure diagram description.

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral)

In addition, you can track the earlier defined peripheral’s UUID and check, if it matches the DEVICE_SERVICE_UUID variable using the “didDiscoverServices peripheral” method. So, if it contains a similar UUID, the connection between devices could be established. Otherwise, the warning might be printed for debugging purposes. This is step four [4] from the BLE connection procedure diagram description.

func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?)

Finally, if the device suddenly disconnects, there is the “didDisconnectPeripheral” method for organizing the following events regarding your iOS project intentions.

func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?)

Ultimately, here is the flow chart of how the BLE connection is organized for making it straightforward and the demo code attached for description.

Picture 3— The BLE connection flow chart by freecodecamp.org website.

P.S. Add your Bluetooth request message to the Info.plist file here:

Privacy - Bluetooth Always Usage Description
Picture 3 — iOS Bluetooth permission request message.

Now, you are ready to call the “connect()” method for establishing the BLE connection with the peripheral where the central manager delegate will be set and initialized via this line of code:

centralManager = CBCentralManager(delegate: self, queue: .global());

Happy coding!

--

--

Аλέξιος
Аλέξιος

No responses yet