Article directory
- 1. Bluetooth BLE
- 2. How do Bluetooth devices connect and interact?
- 3. Bluetooth connection
1. Bluetooth BLE
BLE is the abbreviation of Bluetooth 4.0 (Bluetooth low energy), which is characterized by low power consumption.
2. How do Bluetooth devices connect and interact?
As long as the device integrates the Bluetooth BLE module, it can interact through the Bluetooth protocol stack (GATT, ATT, L2CAP). Both iPhone and Mac have integrated BLE, and we can interact with the underlying Bluetooth protocol stack through the framework.
For example: When the iPhone is used as a central device, Remote Peripheral (CBPeripheral, CBCharacteristic, CBService) is managed through CBCentralManager.
When the iPhone is used as a peripheral device, services are provided through CBPeripheralManager, variable CBMutableService, and CBMutableCharacteristic.
The difference and specification between the central device and the peripheral device
中心设备Central
is the device that initiates the Bluetooth connection and manages the peripheral device.
The specification of the central device needs to provide three functions:
1. Search for connected peripherals;
2. Interact with the data provided by the peripheral;
3. Subscribe to a Characteristic that will notify you when the data changes.
外设Peripheral
The party that provides data by broadcasting data packets through Radio (radio broadcasting equipment). The specification of the peripheral also needs to provide three functions:
1. Publish and broadcast service Service;
2. Respond to read and write requests for characteristics;
3. Respond to subscription requests for characteristics.
3. Bluetooth connection
1. Initialize Bluetooth Center
CBCentralManager is the central device manager and sets up the proxy
let dic = [CBCentralManagerOptionRestoreIdentifierKey: kRestoreIdentifierKey]
centralManager = CBCentralManager.init(delegate: self, queue: .main, options: nil)
Options:
CBCentralManagerOptionShowPowerAlertKey
Used to display a warning dialog box to the user if the Bluetooth system is turned off when the central management class is initialized. This field corresponds to an object of type NSNumber. The default value is NO.
CBCentralManagerOptionRestoreIdentifierKey
The unique identifier of the central manager. The system identifies a specific central manager based on this identifier. In order to continue executing the application, the identifier must remain unchanged before the central management can be restored. kind
Determine the Bluetooth status and obtain whether the current device can be used as a central
// MARK: - CBCentralManagerDelegate
extension DKCBCenterManager: CBCentralManagerDelegate {
// 蓝牙状态
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .poweredOn:
scanBluetooth()
case .poweredOff:
delegate?.bleDidUpdateState(central)
default:
break
}
}
}
- Status unknownCBCentralManagerStateUnknown
= 0, - The connection is disconnected and
CBCentralManagerStateResetting is about to be reset, - The platform does not support BluetoothCBCentralManagerStateUnsupported
, - Unauthorized Bluetooth use hovertree.com
CBCentralManagerStateUnauthorized, - Bluetooth turns off
CBCentralManagerStatePoweredOff, - Bluetooth is turned on normally
CBCentralManagerStatePoweredOn,
2. Scan Bluetooth
let options: [String: Any] = [CBCentralManagerScanOptionAllowDuplicatesKey: NSNumber(value: false)]
centralManager.scanForPeripherals(withServices: nil, options: options)
-
UUID
represents the service ID of the peripheral. When the serviceUUIDs parameter is nil, all discovered peripherals will be returned (Apple does not recommend this approach); when the service ID is filled in, the system will return the peripherals corresponding to the service ID. -
options
CBCentralManagerScanOptionAllowDuplicatesKey
allows repeated scanning of the device. The default is NO. The official recommendation is that this value is NO. When it is YES, it may have an impact on battery life. It is recommended to use it only when necessary. The UUID of the service you want to scan corresponds to
CBCentralManagerScanOptionSolicitedServiceUUIDsKey
an NSArray value.
3. Stop scanning
centralManager?.stopScan()
4. Connect Bluetooth
let options = [CBConnectPeripheralOptionNotifyOnNotificationKey: true]
centralManager?.connect(peripheral, options: nil)
CBConnectPeripheralOptionNotifyOnConnectionKey
When the application is suspended, and the peripheral device is successfully connected, whether to display a warning dialog box to the user, corresponding to the NSNumber object, the default value is NO.
CBConnectPeripheralOptionNotifyOnDisconnectionKey
When the application is suspended, and the peripheral device is disconnected, whether to display a warning dialog box to the user. , corresponding to the NSNumber object, the default value is NO.
CBConnectPeripheralOptionNotifyOnNotificationKey
When the application is suspended, as long as it receives the notification of the given peripheral, whether the pop-up box will be displayed.
5. Get connected devices
// 重新获取当前连接着的设备列表
var peripheralArray = centralManager.retrieveConnectedPeripherals(withServices: [peripheraUUID])
// 重新获取已发现的设备列表
guard let bleUUID = bleUUID else { return }
peripheralArray = centralManager.retrievePeripherals(withIdentifiers: [bleUUID])
6. Disconnect Bluetooth
centralManager?.cancelPeripheralConnection(peripheral)
7. Bluetooth Center Agent
CBCentralManagerDelegate
7.1 Bluetooth status
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .poweredOn:
scanBluetooth()
case .poweredOff:
delegate?.bleDidUpdateState(central)
default:
break
}
}
7.2 Discover Bluetooth devices
func centralManager(_ central: CBCentralManager,
didDiscover peripheral: CBPeripheral,
advertisementData: [String: Any],
rssi RSSI: NSNumber) {
}
7.3 Bluetooth connection
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
stopScanBluetooth()
// 连接蓝牙设备的代理
peripheral.delegate = self
self.peripheral = peripheral
}
7.4 Bluetooth connection failed
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
DKLog("*************** 蓝牙连接失败")
delegate?.bleDidFailToConnectPeripheral(peripheral, error: error)
}
7.5 Bluetooth disconnection
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
DKLog("*************** 断开蓝牙连接")
delegate?.bleDidDisconnectPeripheral(peripheral, error: error)
}
7.6 Bluetooth connection recovery
func centralManager(_ central: CBCentralManager, willRestoreState dict: [String: Any]) {
let arr = dict[CBCentralManagerRestoredStatePeripheralsKey]
guard let peripheralArr = arr as? [CBPeripheral] else {
return
}
let meek = peripheralArr[0]
DKLog("*************** 蓝牙恢复连接 \(meek)")
// self.connectPeripheral(meek, delegate: self)
}
8. Bluetooth device service
CBPeripheralDelegate
8.1 Read Bluetooth RSSI
func peripheral(_ peripheral: CBPeripheral, didReadRSSI RSSI: NSNumber, error: Error?) {
delegate?.bleDidReadRSSI(RSSI)
}
8.2 Discover Bluetooth services
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
// DKLog("*************** 发现蓝牙服务 \(peripheral.services)")
peripheral.services?.forEach({ service in
peripheral.discoverCharacteristics(nil, for: service)
})
}
8.3 Subscribing to Bluetooth Features
func peripheral(_ peripheral: CBPeripheral,
didDiscoverCharacteristicsFor service: CBService,
error: Error?) {
// DKLog("*************** 订阅蓝牙特征 \(service.characteristics)")
if service.uuid.uuidString == configuration?.serviceUUIDString.uppercased() {
characteristic_serve = service
service.characteristics?.forEach({ characteristic in
if characteristic.uuid.uuidString == configuration?.writeCharacteristicUUIDString.uppercased() {
characteristic_write = characteristic
}
if characteristic.uuid.uuidString == configuration?.readCharacteristicUUIDString {
characteristic_read = characteristic
peripheral.setNotifyValue(true, for: characteristic)
}
})
}
delegate?.bleDidDiscoverCharacteristicsForService(peripheral, error: error)
}
8.4 Bluetooth subscription successful
func peripheral(_ peripheral: CBPeripheral,
didUpdateNotificationStateFor characteristic: CBCharacteristic,
error: Error?) {
DKLog("*************** 订阅蓝牙通知 成功")
delegate?.bleDidUpdateNotificationStateForCharacteristic(characteristic, error: error)
}
8.5 Bluetooth write data callback
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
DKLog("*************** didWriteValueForCharacteristic")
DKLog(error)
DKLog(characteristic)
}
8.6 Reading data via Bluetooth
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
delegate?.bleDidUpdateValue(characteristic, error: error)
}
9. Bluetooth writing data
peripheral.writeValue(wdata, for: characteristic_write, type: .withoutResponse)
10. Reading data via Bluetooth
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
delegate?.bleDidUpdateValue(characteristic, error: error)
}
}