[CoreBluetooth] Basics for handling BLE on iOS

Introduction

Since I have touched BLE, I will summarize it as a memorandum.

This is different for those who have seen it, right? If there is something like that, please point it out.

environment

iOS 13.3 xcode 11.5 swift 5.2.4

What is BLE in the first place?

The official name is ** Bluetooth Low Energy **, which is a standard specializing in low power consumption and low cost. There are many changes from the previous standard (Bluetooth Classic) and it is not compatible. (But there seems to be dual mode technology of BLE and Bluetooth classic?)

BLE has the following features.

Characteristic

--Low power consumption

Glossary of BLE

Central

Play a role in controlling communication Example) iPhone, PC, etc.

Peripheral

It does not have a communication control function because it communicates in response to the request from Central.
Example) Beacon

--Service: Always exists in the peripheral and represents a functional unit --Characteristic: Contains the data actually exchanged

Advertise

Peripherals keep sending information about themselves on a regular basis by unidirectional communication (broadcast communication) so that the central can recognize itself.

RSSI(Received signal strength indication) Numerical value (relative value) indicating the strength of the received signal entering the receiver input

Procedure to connect to BLE

It will be connected in roughly 3 steps.

** 1. Peripherals send advertisements ** ** 2. Central receives the advertisement and sends a connection request ** ** 3. Connection completed **

As a procedure, you can easily connect.

Implementation procedure for connecting to BLE equipment

1. Introduction of framework

Import the framework "Core Bluetooth".

import CoreBluetooth

2. Definition of required variables

Then, define the instance (member) variables required this time.

var centralManager: CBCentralManager!
var peripheral: CBPeripheral!

3. CBCentral Manager instantiation

Create an instance to be used in the main this time.

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

4. Start peripheral scan

Use the instance you just created to start scanning peripherals.

self.centralManager.scanForPeripherals(withServices: nil, options: nil)

You can also specify a UUID to narrow down the scan to specific peripherals.

let services = [CBUUID(string: "○○○")]
self.centralManager.scanForPeripherals(withServices: services, options: nil)

5. Peripheral connection

If a peripheral scan of 4 finds a peripheral, the delegate method is also called: The first line in this function makes a connection to the discovered peripheral. Also, since we want to specify a delegate for that peripheral, assign it to the instance variable defined earlier.

func centralManager(_ central: CBCentralManager,
                    didDiscover peripheral: CBPeripheral,
                    advertisementData: [String: Any], rssi RSSI: NSNumber) {
    self.centralManager.connect(peripheral, options: nil)
    self.peripheral = peripheral
}

6. Get service

If you connect to the peripheral in 5, the delegate method will be called: The first line in this function specifies the delegate. Then, get the service in the second line in the function.

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
    self.peripheral.delegate = self
    self.peripheral.discoverServices(nil)
}

7. Get characteristic

When the service is acquired in 6, the following delegate method is called. The first line in the function gets the characteristic.

func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
    self.peripheral.discoverCharacteristics(nil, for: (peripheral.services?.first)!)
}

Summary

This time, I summarized "How to handle BLE with Swift" as a memorandum. I think there are still some parts that are missing, wrong, and inadequate in understanding, so I would like to make appropriate corrections.

Whole source code

import UIKit
import CoreBluetooth

class ViewController: UIViewController{
    
    var centralManager: CBCentralManager!
    var peripheral: CBPeripheral!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.centralManager = CBCentralManager(delegate: self, queue: nil, options: nil)
    }
    
    //Start scanning by pressing a button
    @IBAction func scanButton(_ sender: Any) {
        self.centralManager.scanForPeripherals(withServices: nil, options: nil)
    }
}

extension ViewController: CBCentralManagerDelegate {
    //Returns BLE status
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        switch central.state {
        case CBManagerState.poweredOn:
            print("The power is on.")
        case CBManagerState.poweredOff {
            print("The power is off.")
        default:
            break
        }
    }
    
    //Called after scanning
    func centralManager(_ central: CBCentralManager,
                        didDiscover peripheral: CBPeripheral,
                        advertisementData: [String: Any], rssi RSSI: NSNumber) {
        self.centralManager.connect(peripheral, options: nil)
        self.peripheral = peripheral
        self.centralManager.stopScan()    //Stop scanning
    }
    
    //Called when connecting
    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
        self.peripheral.delegate = self
        self.peripheral.discoverServices(nil)
    }
}

extension ViewController: CBPeripheralDelegate {
    //Called when getting the service
    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        self.peripheral.discoverCharacteristics(nil, for: (peripheral.services?.first)!)
    }
    
    //Called when acquiring characteristic
    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
    }
}

reference

First BLE / Marubun CorporationTry running BLE sample with iOS Swift

Recommended Posts

[CoreBluetooth] Basics for handling BLE on iOS
Notes for using BLE with iOS apps
[Ruby] Exception handling basics
Ruby on Rails basics