蓝牙4.0是低电量模式因此也叫4.0BLE。本文将使用iOS系统提供的CoreBluetooth框架。app
CoreBluetooth框架的核心实际上是两个东西,peripheral和central, 能够理解成外设和主设备(中心)。框架
左边是主设备模式,即开发的app在手机上,手机链接其它硬件(外设);
右边的是外设模式,手机做为外设,其它硬件设备做为主设备。本文只讲主设备模式,这种应用场景是最多的。优化
外设peripheral(主设备模式下,与手机链接的硬件是peripheral,例如AppleWatch)、服务service、特征值characteristic的关系以下:ui
每一个外设下都有多个服务,每一个服务里面有多个特征值。服务和特征值都有一个惟一识别码UUID。与特征值交互的模式经常使用有三种:读取(read)、写入(write)、还有监听(notify)。咱们须要根据与硬件工程师所订的协议找到对应服务里面的特征值,读取或写入这个特征值。例如,咱们须要知道外设的硬件的电量,咱们须要读取约定好的服务里的特征值,来获取电量。若是咱们须要向外设发送指令,只须要找到对应的特征值,写入数据。spa
这里简单介绍一下系统CoreBluetooth使用的方法及代理。以便对后面使用第三方库LGBluetooth更好地理解及使用和修改第三方内部的方法符合业务场景需求。代理
1.创建主设备模式code
#import <CoreBluetooth/CoreBluetooth.h> CBCentralManager *manager = [[CBCentralManager alloc]initWithDelegate:self queue:nil];
2.扫描外设(discover)orm
//扫描设备 [manager scanForPeripheralsWithServices:nil options:nil]; //扫描到设备会进入方法 -(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI;
3.链接外设(connect)blog
[manager connectPeripheral:peripheral options:nil]; //链接外设成功的委托 - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral; //外设链接失败的委托 - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error; //断开外设的委托 - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;
4.扫描外设中的服务和特征(discover)ip
- 4.1 获取外设的services - 4.2 获取外设的Characteristics,获取Characteristics的值
//扫描到服务 -(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error; //找到服务后,扫描到服务里面的特征值 -(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error;
5.与外设作数据交互(字节处理)
//在特征值写数据 [peripheral writeValue:value forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
6.订阅Characteristic的通知
//订阅通知 [peripheral setNotifyValue:YES forCharacteristic:characteristic];
7.断开链接(disconnect)
//断开链接的回调 -(void)disconnectPeripheral:(CBCentralManager *)centralManager peripheral:(CBPeripheral *)peripheral { //中止扫描 [centralManager stopScan]; //断开链接 [centralManager cancelPeripheralConnection:peripheral]; }
1.在Appdelegate初始化LGCentralManager
#import <LGBluetooth/LGBluetooth.h> [LGCentralManager sharedInstance]
2.对LGBlueTooth封装一个类,用来处理业务的蓝牙指令(CommunicationManager)
\\链接设备 - (void)connectPeripheral:(LGPeripheral *)peripheral completion:(CompletionBlock)block { self.lgPeripheral = peripheral; self.connectBlock = block; __weak CommunicationManager *weakSelf = self; [peripheral connectWithCompletion:^(NSError *error) { if (!error) { weakSelf.shouldRetryConnect = YES; [weakSelf setupServicesWithPeripheral:peripheral completion:block]; } else { block(NO); } }]; } \\链接设备成功后,遍历外设的服务,保存约定好的须要读写的特征值 - (void)setupServicesWithPeripheral:(LGPeripheral *)peripheral completion:(CompletionBlock)block { self.connectBlock = block; [self defaultCharacteristicSetting]; self.lgPeripheral = peripheral; __weak CommunicationManager *weakSelf = self; [peripheral discoverServicesWithCompletion:^(NSArray *services, NSError *error) { for (LGService *service in services) { NSLog(@"serve uuidString:%@", service.UUIDString); if ([service.UUIDString isEqualToString:kNewOperationService]) { [service discoverCharacteristicsWithCompletion:^(NSArray *characteristics, NSError *error) { for (LGCharacteristic *characteristic in characteristics) { NSLog(@"characteristic:%@", characteristic.UUIDString); if ([characteristic.UUIDString isEqualToString:kNewWriteCharacteristic]) { weakSelf.deviceNewWriteCharacterstic = characteristic; [weakSelf checkIfAllReady]; } else if ([characteristic.UUIDString isEqualToString:kNewNotifyCharacteristic]) { weakSelf.deviceNewNotifyCharacterstic = characteristic; [characteristic setNotifyValue:YES completion:nil onUpdate:^(NSData *data, NSError *error) { [weakSelf handleData:data]; [weakSelf checkIfAllReady]; }]; } else if ([characteristic.UUIDString isEqualToString:kNewReadCharacteristic]) { weakSelf.deviceNewReadCharacterstic = characteristic; [characteristic readValueWithBlock:^(NSData *data, NSError *error) { if (!error) { peripheral.macAddress = [self convertNewMacAddressWithData:data]; NSLog(@"mac data:%@", peripheral.macAddress); [weakSelf checkIfAllReady]; } }]; } } }]; } } }]; }
3.发送蓝牙指令(OperationType是业务的蓝牙指令枚举,例如查电量、关机、重启、设备版本信息、设备改名等指令)
- (void)performOperationType:(OperationType)operationType object:(id)object completionBlock:(OperationBlock)block { self.operationBlock = block; //根据不一样的蓝牙指令处理蓝牙数据 NSData *data = [self dataWithOperationType:operationType object:object]; if (data == nil) { return; } //写入特征值 [self.writeCharacteristic writeValue:data completion:^(NSError *error) { NSLog(@"functionCode:%d",[self getFunctionCodeByOperationType:operationType]); if (!error) { NSLog(@"成功发送特征值数据"); } }]; //以后会根据监听约定好的特征值返回到蓝牙指令执行结果做进一步处理 }
感谢阅读,但愿对你们认识蓝牙开发的思路有所帮助,蓝牙里面开发还涉及到更加复杂的功能及优化,譬如设备搜索筛选、设备重连实现、设备固件升级优化等,因为时间关系,只做流程性的蓝牙开发的介绍。谢谢。