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:
0x180D
或0000180D-0000-1000-8000-00805F9B34FB
)。 - 自定义 UUID :生成唯一 UUID(如使用
uuidgen
命令)。
4.3 连接优化
-
自动重连 :监听断开事件并重新连接。
swiftfunc 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 管理、后台模式、数据分片。
- 适用场景:健康设备、智能家居、传感器数据采集等低功耗实时通信。