iOS 蓝牙开发基础知识梳理

1. 蓝牙基础

1.1 蓝牙类型

  • BLE(Bluetooth Low Energy)
    • 低功耗,适用于间歇性数据传输(如健康设备、传感器)。
    • iOS 主要支持 BLE(4.0+)。
  • 经典蓝牙(Bluetooth Classic)
    • 高带宽,持续传输(如音频设备)。
    • iOS 不支持经典蓝牙开发(仅支持连接配对设备,如耳机)。

1.2 角色划分

角色 描述 核心类
Central(中心设备) 主动扫描并连接外围设备(如 iPhone 作为中心设备连接手环)。 CBCentralManager, CBPeripheral
Peripheral(外围设备) 提供服务和数据(如手环作为外围设备广播心率数据)。 CBPeripheralManager, CBMutableService

2. Core Bluetooth 核心类

2.1 Central 角色

  • CBCentralManager:管理中心设备,扫描、连接外围设备。
  • CBPeripheral:表示连接的外围设备,包含服务、特征等数据。
  • CBService:外围设备提供的服务(如心率服务)。
  • CBCharacteristic:服务中的特征,用于读写数据或订阅通知。

2.2 Peripheral 角色

  • CBPeripheralManager:管理外围设备,广播服务。
  • CBMutableService:可修改的服务(定义 UUID 和特征)。
  • CBMutableCharacteristic:可修改的特征(定义权限和值)。

3. BLE 开发流程(Central 模式)

3.1 初始化 Central Manager

swift 复制代码
import CoreBluetooth

class BluetoothManager: NSObject {
    var centralManager: CBCentralManager!
    
    override init() {
        super.init()
        centralManager = CBCentralManager(delegate: self, queue: nil)
    }
}

extension BluetoothManager: CBCentralManagerDelegate {
    // 检测蓝牙状态
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        switch central.state {
        case .poweredOn:
            print("蓝牙已开启,开始扫描设备")
            central.scanForPeripherals(withServices: nil, options: nil)
        case .poweredOff:
            print("蓝牙未开启")
        default: break
        }
    }
}

3.2 扫描设备

swift 复制代码
// 扫描所有设备(指定 serviceUUID 可过滤目标设备)
centralManager.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey: false])

// 发现设备回调
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) {
    print("发现设备: \(peripheral.name ?? "未知设备"), RSSI: \(RSSI)")
    // 根据设备名或 UUID 筛选目标设备
    if peripheral.name?.contains("MyDevice") == true {
        centralManager.connect(peripheral, options: nil)
    }
}

3.3 连接设备

swift 复制代码
// 发起连接
centralManager.connect(peripheral, options: nil)

// 连接成功回调
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
    print("连接成功: \(peripheral.name ?? "")")
    peripheral.delegate = self
    peripheral.discoverServices(nil) // 发现所有服务
}

// 连接失败回调
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
    print("连接失败: \(error?.localizedDescription ?? "")")
}

3.4 发现服务与特征

swift 复制代码
extension BluetoothManager: CBPeripheralDelegate {
    // 发现服务
    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        guard let services = peripheral.services else { return }
        for service in services {
            print("发现服务: \(service.uuid)")
            // 发现服务的特征
            peripheral.discoverCharacteristics(nil, for: service)
        }
    }
    
    // 发现特征
    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
        guard let characteristics = service.characteristics else { return }
        for characteristic in characteristics {
            print("特征 UUID: \(characteristic.uuid)")
            // 订阅通知(如需接收数据)
            if characteristic.properties.contains(.notify) {
                peripheral.setNotifyValue(true, for: characteristic)
            }
            // 读取特征值
            peripheral.readValue(for: characteristic)
        }
    }
}

3.5 读写数据

swift 复制代码
// 读取特征值
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
    if let data = characteristic.value {
        let value = String(data: data, encoding: .utf8) ?? "无法解析"
        print("收到数据: \(value)")
    }
}

// 写入数据(需特征支持写入)
func writeData(to characteristic: CBCharacteristic, peripheral: CBPeripheral) {
    let data = "Hello BLE".data(using: .utf8)!
    peripheral.writeValue(data, for: characteristic, type: .withResponse)
}

4. 关键注意事项

4.1 权限与配置

  • Info.plist 配置

    xml 复制代码
    <key>NSBluetoothAlwaysUsageDescription</key>
    <string>需要蓝牙权限以连接设备</string>
    <key>NSBluetoothPeripheralUsageDescription</key>
    <string>需要蓝牙权限以连接设备</string> <!-- 兼容旧版本 -->
  • 后台模式 (保持连接):

    xml 复制代码
    <key>UIBackgroundModes</key>
    <array>
        <string>bluetooth-central</string>
        <string>bluetooth-peripheral</string>
    </array>

4.2 UUID 规范

  • 标准 UUID :16 位或 128 位(如心率服务 UUID:0x180D0000180D-0000-1000-8000-00805F9B34FB)。
  • 自定义 UUID :生成唯一 UUID(如使用 uuidgen 命令)。

4.3 连接优化

  • 自动重连 :监听断开事件并重新连接。

    swift 复制代码
    func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
        print("设备断开,尝试重连...")
        central.connect(peripheral, options: nil)
    }
  • 超时处理 :使用 Timer 限制连接时间。


5. 常见问题与解决方案

问题 解决方案
扫描不到设备 确认设备处于广播模式,检查蓝牙权限,确保 UUID 匹配。
连接不稳定 优化信号环境,实现自动重连逻辑,检查设备电量。
读写数据失败 确认特征具有正确的权限(.read, .write),使用正确的写入类型(.withResponse)。
后台模式断开连接 启用 bluetooth-central 后台模式,使用 CBCentralManagerOptionRestoreIdentifierKey 恢复连接。
数据传输不完整 分包发送大数据(每包 ≤ 20 字节),接收端拼接数据。

6. 第三方库推荐

  • Bluejay:简化 BLE 操作,支持链式调用。
  • SwiftBluetooth:封装 Core Bluetooth,提供更简洁的 API。
  • BabyBluetooth(OC):简化流程,适合快速开发。

总结

  • 核心步骤:初始化 → 扫描 → 连接 → 发现服务/特征 → 读写数据。
  • 关键代理CBCentralManagerDelegate, CBPeripheralDelegate
  • 注意事项:权限配置、UUID 管理、后台模式、数据分片。
  • 适用场景:健康设备、智能家居、传感器数据采集等低功耗实时通信。
相关推荐
鸿蒙布道师32 分钟前
鸿蒙NEXT开发数值工具类(TS)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
程序员老刘5 小时前
谨慎升级macOS 15.4,规避 ITMS-90048 错误
flutter·macos·ios
一牛7 小时前
Metal 进阶:读取可绘制对象的像素
ios·swift·计算机图形学
90后的晨仔7 小时前
什么是WebSocket ?ios 中如何使用?
ios
鸿蒙布道师10 小时前
鸿蒙NEXT开发日期工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
无知的前端10 小时前
iOS开发,runtime实现切片编程原理以及实战用例
ios·面试·性能优化
木西11 小时前
React Native项目初始化及相关通用工具集成
android·react native·ios
胡八一1 天前
Window调试 ios 的 Safari 浏览器
前端·ios·safari
karshey1 天前
【IOS webview】源代码映射错误,页面卡住不动
ios