最近公司项目少了很多,所以有时间把之前项目中封装的蓝牙库分享一下。
原生的CoreBluetooth库采用代理的方式实现数据反馈或状态更新,这样有个缺点就是代码很离散,且会导致与业务层耦合度高,不便于移植。再有就是业务层读写数据时,需要关心特征值以及应答模式等太多底层的东西。如下:
- (void)writeValue:(NSData *)data forCharacteristic:(CBCharacteristic *)characteristic type:(CBCharacteristicWriteType)type;
鉴于此原因(槽点),所以将CoreBlueTooth再次封装。整体模块设计图如下:
说明:
该封装库包含两个模块。 BLEKit 是客户端管理模块,提供蓝牙控制API,以及蓝牙数据读写协议API
BLEService模块是蓝牙应用层协议(业务层协议)的封装,提供给业务层读写以及数据通知API
使用方法:
一、CentralManager以状态机的方式表现当前的状态
/**
* @enum BLECentralState
*
* @discussion BLE 中心设备管理器状态机
* @constant BLECentralStateInvalid: 无效状态,蓝牙未开启 or 蓝牙不可用
* @constant BLECentralStateIdle: 空闲状态,没有开始工作 or 工作中断
* @constant BLECentralStateScaning: 正在扫描周边设备状态
* @constant BLECentralStateUnDiscovered: 未发现周边状态,超时或者其他原因
* @constant BLECentralStateDiscovered: 已发现周边状态
* @constant BLECentralStateConnecting: 正在连接外设状态
* @constant BLECentralStateUnConnected: 未连接成功,连接失败状态
* @constant BLECentralStateConnected: 连接成功状态,注意:此状态表示外设已经连接且有可用服务
* @constant BLECentralStateRuning: BLE中心设备正常工作状态,表示可以进行蓝牙数据通信
*/
typedef NS_ENUM(NSInteger, BLECentralState)
{
BLECentralStateInvalid,
BLECentralStateIdle,
BLECentralStateScaning,
BLECenteralStateUnDiscovered,
BLECentralStateDiscovered,
BLECentralStateConnecting,
BLECentralStateUnConnected,
BLECentralStateConnected,
BLECentralStateRuning,
};
控制类API如下:
/**
* 开始扫描周边外围设备,直到调用stopScan
*/
- (void)startScan;
/**
* 开始扫描周边外围设备
*
* @param timeout 扫描超时时间
*/
- (void)startScanWithTimeout:(NSInteger)timeout;
/**
* 停止扫描
*/
- (void)stopScan;
/**
* 开始连接外设
*
* @param bracelet 外围设备属性
*/
- (void)connect:(BLEPeripheral *)bracelet;
/**
* 断开蓝牙连接
*/
- (void)disConnect;
状态变化采用通知的方式上报给业务层,考虑存在多个业务模块监听BLE状态
/**
* BLE Centeral 状态变化采用通知的方式上报给业务层,考虑存在多个业务模块监听BLE状态,
* 所以使用通知作为交互模式。
*/
extern NSString *const BLECentralStateDidChangedNotification;
二、BLESerivice 基于CentralManager模块内的协议实现 业务层协议stackProtocol,CentralManager模块内只提供协议通道,具体的协议格式需要业务层定义。
三、具体的API调用方式请参考源码:
https://github.com/tomtcl/BluetoothKit