iOS蓝牙系列之二:实际开发蓝牙(Swift版)

前一篇文章介绍了蓝牙的基础知识。今天就说下具体实践。

说起蓝牙开发,听起来高大上,其实就像“手机和外设谈恋爱”,核心是:发现-连接-读写,掌握这一点,就能很好地开发了。

下面开始介绍
一、准备工作

  1. 导入Framework和设置蓝牙权限
    在项目中导入CoreBluetooth框架,并在Info.plist中添加蓝牙权限描述:
    NSBluetoothAlwaysUsageDescription
    需要蓝牙权限连接设备
  2. 创建并初始化蓝牙管理器
    创建一个BlueCentralManager实例,管理本应用程序的蓝牙:
    import Foundation
    import CoreBluetooth

class BluetoothManager: NSObject {
var centralManager: CBCentralManager!
var connectedPeripheral: CBPeripheral? // 存储连接的外设

let myDeviceName = "xxxx"
let serviceUUID = CBUUID(string: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
let characterUUID = CBUUID(string: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")

override init() {
    super.init()
    centralManager = CBCentralManager(delegate: self, queue: nil)
}

}
创建好实例后,就按蓝牙六个步骤进行操作。至于为什么是这样?我想这就是蓝牙开发的步骤,没有好说的。

二、蓝牙开发六步走

  1. 检查蓝牙状态
    通过代理方法确定手机蓝牙是否可用:
    extension BluetoothManager: CBCentralManagerDelegate {
    //检查蓝牙状态
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
    switch central.state {
    case .poweredOn:
    print(“蓝牙已开启,开始扫描设备”)
    central.scanForPeripherals(withServices: nil, options: nil)
    case .poweredOff:
    print(“请打开蓝牙”)
    default: break
    }
    }
    }
    注意这里需要在CBCentralManagerDelegate代理实现,后面的步骤也是如此
    通过这一步确定了手机蓝牙可用后,就继续下一步
  2. 扫描外设
    发现设备时,会触发didDiscover回调。
    这里可以显示蓝牙设备列表,也可以找我们固定想要找的蓝牙设备,本实例就实现后者。例如假设我们找名字为“MyDevice”的设备:
    extension BluetoothManager: CBCentralManagerDelegate {
    //扫描外设
    func centralManager(_ central: CBCentralManager,
    didDiscover peripheral: CBPeripheral,
    advertisementData: [String : Any],
    rssi RSSI: NSNumber) {
    if peripheral.name == myDeviceName {
    print(“找到设备:(peripheral)”)
    connectedPeripheral = peripheral
    central.stopScan() // 停止扫描
    central.connect(peripheral, options: nil) // 发起连接
    }
    }
    }
  3. 连接设备
    连接成功后会触发didConnect回调,此时要设置外设的代理:
    extension BluetoothManager: CBCentralManagerDelegate {
    //连接设备
    func centralManager(_ central: CBCentralManager,
    didConnect peripheral: CBPeripheral) {
    print(“连接成功!”)
    peripheral.delegate = self
    peripheral.discoverServices(nil) // 开始搜索服务
    }

}
在连接设备成功之后,就开始搜索服务.注意:
前面三步是使用CBCentralManagerDelegate代理,
后面的步骤就使用CBPeripheralDelegate代理.

  1. 发现服务与特征
    对于一个外设来说,可能有多个服务(Service),而每个服务包含多个特征(Characteristic):
    extension BluetoothManager: CBPeripheralDelegate {
    // 发现服务
    func peripheral(_ peripheral: CBPeripheral,
    didDiscoverServices error: Error?) {
    guard let services = peripheral.services else { return }
    for service in services {
    print(“发现服务:(service.uuid)”)
    // 搜索该服务的所有特征
    if service.uuid == serviceUUID {
    peripheral.discoverCharacteristics(nil, for: service)
    }
    }
    }
    }
    extension BluetoothManager: CBPeripheralDelegate {
    // 发现特征
    func peripheral(_ peripheral: CBPeripheral,
    didDiscoverCharacteristicsFor service: CBService,
    error: Error?) {
    guard let characteristics = service.characteristics else { return }
    for char in characteristics {
    print(“特征UUID:(char.uuid)”)
    if char.uuid == characterUUID {
    let data = “Hello Buletooth”.data(using: .utf8)
    sendData(characteristic: char, data: data!)
    }
    }
    }
    }
  2. 读写数据
    读取数据:直接调用readValue
    写入数据:注意选择写入类型(withResponse需对方确认)
    extension BluetoothManager: CBPeripheralDelegate {
    // 发送数据示例
    func sendData(characteristic: CBCharacteristic, data: Data) {
    guard let peripheral = connectedPeripheral else { return } peripheral.writeValue(data, for: characteristic, type: .withResponse) } // 接收数据回调
    func peripheral(_ peripheral: CBPeripheral,
    didUpdateValueFor characteristic: CBCharacteristic,
    error: Error?) {
    if let data = characteristic.value {
    let message = String(data: data, encoding: .utf8)
    print(“收到数据:(message ?? “”)”)
    }
    }
    }
  3. 断开连接
    extension BluetoothManager: CBPeripheralDelegate {
    //断开连接
    func disconnect() {
    if let peripheral = connectedPeripheral {
    centralManager.cancelPeripheralConnection(peripheral)
    }
    }
    }
    以上就是蓝牙连接的6个步骤,每一步像环一样,一环紧扣一环,环环相扣。

下面再讲下开发过程中的注意事项。
三、注意事项:
1.权限问题:iOS18要求蓝牙权限必须在Info.plist中明确声明。
2.主线程问题:所有蓝牙回调默认在后台线程,更新UI记得切回主线程。
3.特征属性:写数据前检查特征的.properties是否包含.write

以上就是蓝牙开发的整体流程。
其实做过之后,比较简单,按固定流程开发即可。最关键的是要自己去实践一把。

声明:来自程序员华仔,仅代表创作者观点。链接:https://eyangzhen.com/2112.html

程序员华仔的头像程序员华仔

相关推荐

关注我们
关注我们
购买服务
购买服务
返回顶部