在开发与硬件设备(如智能手环、健康监测设备、BLE模块)交互的 iOS 应用时,蓝牙低功耗(Bluetooth Low Energy, 简称 BLE)通信是最常见的方式之一。
本文将以 Objective-C 为基础语言,介绍我在工作中如何使用 CoreBluetooth 框架进行 BLE 设备连接、服务发现、数据通信等功能,适用于需要通过 iOS 设备连接蓝牙设备的开发者,有需要的朋友可以参考一下。
- App 添加蓝牙权限(
Info.plist中配置):
<key>NSBluetoothAlwaysUsageDescription</key>
<string>需要使用蓝牙连接外设</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>蓝牙功能用于连接设备</string>
- 引入框架:
#import <CoreBluetooth/CoreBluetooth.h>
基本流程概览
- 初始化
CBCentralManager - 扫描设备
- 连接设备
- 发现服务和特征
- 读写数据
- 接收通知
核心代码示例(基于 OC)
一、初始化和开始扫描设备
@interface BluetoothManager : NSObject <CBCentralManagerDelegate, CBPeripheralDelegate>
@property (nonatomic, strong) CBCentralManager *centralManager;
@property (nonatomic, strong) CBPeripheral *connectedPeripheral;
@end
@implementation BluetoothManager
- (instancetype)init {
self = [super init];
if (self) {
// 初始化中心管理器
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
return self;
}
// 中心管理器状态更新回调
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
if (central.state == CBManagerStatePoweredOn) {
NSLog(@"蓝牙已开启,开始扫描设备");
[self.centralManager scanForPeripheralsWithServices:nil options:nil];
} else {
NSLog(@"蓝牙不可用,状态:%ld", (long)central.state);
}
}
二、发现并连接蓝牙设备
// 扫描到外设
- (void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary<NSString *, id> *)advertisementData
RSSI:(NSNumber *)RSSI {
NSLog(@"发现设备:%@ - RSSI: %@", peripheral.name, RSSI);
// 这里建议使用名称/UUID过滤设备
if ([peripheral.name containsString:@"MyBLE"]) {
self.connectedPeripheral = peripheral;
self.connectedPeripheral.delegate = self;
[self.centralManager stopScan];
[self.centralManager connectPeripheral:peripheral options:nil];
}
}
三、 连接成功并发现服务和特征
// 成功连接设备
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
NSLog(@"已连接设备:%@", peripheral.name);
[peripheral discoverServices:nil]; // 发现所有服务
}
// 发现服务后
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
for (CBService *service in peripheral.services) {
NSLog(@"发现服务:%@", service.UUID);
[peripheral discoverCharacteristics:nil forService:service];
}
}
// 发现特征后
- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverCharacteristicsForService:(CBService *)service
error:(NSError *)error {
for (CBCharacteristic *characteristic in service.characteristics) {
NSLog(@"发现特征:%@", characteristic.UUID);
// 订阅通知
if (characteristic.properties & CBCharacteristicPropertyNotify) {
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
// 读取初始值
if (characteristic.properties & CBCharacteristicPropertyRead) {
[peripheral readValueForCharacteristic:characteristic];
}
}
}
四、 接收数据与写入数据
// 接收到外设返回的数据
- (void)peripheral:(CBPeripheral *)peripheral
didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic
error:(NSError *)error {
NSData *data = characteristic.value;
NSString *hexStr = [ParseDataTool transDataToHexString:data];
NSLog(@"接收到数据: %@", hexStr);
}
// 向设备写入数据
- (void)writeData:(NSData *)data toCharacteristic:(CBCharacteristic *)characteristic {
[self.connectedPeripheral writeValue:data
forCharacteristic:characteristic
type:CBCharacteristicWriteWithResponse];
}
示例:发送指令并接收蓝牙数据包
// 假设你已有某个特征 characteristic
NSString *cmdHex = @"A102B3";
NSData *cmdData = [ParseDataTool transToDataWithString:cmdHex];
[self writeData:cmdData toCharacteristic:characteristic];
常见注意事项
- 中央设备只能连接一个外设,多连接需管理连接状态。
- 蓝牙通信中数据格式严格,建议用工具类(如
ParseDataTool)处理数据。 (我上一篇文章中写到的) - 注意连接断开要做清理操作,并考虑重连逻辑。
对于设备交互类 App(如智能穿戴、健康监测、工业控制)来说,这是非常不错的开发知识分享。如有说错的地方,欢迎大家指正。