1. 工程中导入CoreBluetooth.framework并在相关界面(建议写在父类,便于继承使用)import "CoreBluetooth/CoreBluetooth.h"。
2.初始化CBCentralManager并准备扫描周围蓝牙设备。初始化之后会检测设备是否打开了蓝牙服务:
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
switch (central.state) {
case CBCentralManagerStateUnknown:
break;
case CBCentralManagerStateUnsupported:
NSLog(@"模拟器不支持蓝牙调试");
break;
case CBCentralManagerStateUnauthorized:
break;
case CBCentralManagerStatePoweredOff:
NSLog(@"蓝牙处于关闭状态");
[[NSNotificationCenter defaultCenter]postNotificationName:@"BluthooClose" object:nil];
break;
case CBCentralManagerStateResetting:
break;
case CBCentralManagerStatePoweredOn:
NSLog(@"蓝牙处于打开状态");
[[NSNotificationCenter defaultCenter]postNotificationName:@"BluthooOppen" object:nil];
break;
}}
3.当蓝牙处于正常打开状态,就可以开始搜索周边设备
{UIActivityIndicatorView * IndicatorView;
IndicatorView = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];}//系统自带旋转小菊花
{[self.MyCentralManager stopScan];
[self.MyCentralManager scanForPeripheralsWithServices:nil options:nil];}每次扫描之前先确保扫描动作处于停止状态。
4.扫描到外设走代理方法,并添加到相关数组用于显示在界面
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{
NSLog(@"能发现设备:%@----RSSI-%@---services---%@-----mac——Data---%@---peripheral---%@",peripheral.name,peripheral.RSSI,peripheral.services,advertisementData,peripheral.identifier);
BluetoothModel * bluetooth = [[BluetoothModel alloc]init];
bluetooth.advertisementData = advertisementData;
bluetooth.peripheral = peripheral;
if (YES){
if (self.dataArray.count == 0){
[self.dataArray addObject:bluetooth];
[self.Last_peripheral_arr addObject:peripheral];
}
else{
if (peripheral.name.length > 0) {
for(int i = 0;i < self.dataArray.count; i ++){
if (![self.Last_peripheral_arr containsObject:peripheral]){
[self.dataArray addObject:bluetooth];
[self.Last_peripheral_arr addObject:peripheral];
}
}
}
}
}
[[NSNotificationCenter defaultCenter]postNotificationName:@"reloadTable" object:nil];
}
5.接下来就是连接外设(这里需要注意的是:外设物理MAC地址需要硬件端工程师写在外设属性advertisementData中的kCBAdvDataManufacturerData字段中,用于之后的短线自动重连)。
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
BluetoothModel * bluetooth = [[BluetoothModel alloc]init];
bluetooth = self.dataArray[indexPath.row];
CBPeripheral * Peripheral = bluetooth.peripheral;
NSDictionary * Mac_data = bluetooth.advertisementData;
#pragma mark Mark 外设的物理地址
NSLog(@"------连接的外设的Mac地址------%@",[Mac_data objectForKey:@"kCBAdvDataManufacturerData"]);
[UserDefaultManager SetLocalDataObject:[Mac_data objectForKey:@"kCBAdvDataManufacturerData"] key:BluetoothMac];
[self connectPeripheral:Peripheral];(指向父类中的方法---->[self.MyCentralManager connectPeripheral:peripheral options:nil];)
}
6.连接成功与否
#pragma mark 蓝牙连接设备成功与否的回调
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
// ALERT(@"连接成功");
[self.peripheral discoverServices:nil];
self.peripheral.delegate = self;
[[NSNotificationCenter defaultCenter]postNotificationName:@"Connected" object:nil];
[self cancelScan];
}
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error{
NSLog(@"-------连接失败----原因----%@",error);
/*--取消本地以保存的外设Mac地址--*/
[UserDefaultManager removeLocalDataForKey:BluetoothMac];
ALERT(NSLocalizedString(@"Bluetooth_connection_is_broken", nil));
}
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error
{
#pragma mark 蓝牙断开连接,是否重连
ALERT(NSLocalizedString(@"Bluetooth_connection_is_broken", nil));
}
7.连接成功之后,会搜索外设相关Service和与之对应的Characteristic
#pragma mark 寻找Characteristic找到Service后会调用下面的方法:
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
NSLog(@"寻找到了服务");
NSArray *services = nil;
if (peripheral != self.peripheral) {
NSLog(@"Wrong Peripheral.\n");
return ;
}
if (error != nil) {
NSLog(@"Error %@\n", error);
return ;
}
services = [peripheral services];
if (!services || ![services count]) {
NSLog(@"No Services");
return ;
}
for (CBService *service in services) {
NSLog(@"service:%@",service.UUID);
NSString * str = [NSString stringWithFormat:@"%@",service.UUID];
[peripheral discoverCharacteristics:nil forService:service];
}
}
#pragma mark 找到Characteristic后读取数据,找到Characteristic后会调用下面的delegate方法:
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
NSLog(@"characteristics:%@",[service characteristics]);
NSArray *characteristics = [service characteristics];
[SVProgressHUD showWithStatus:NSLocalizedString(@"The_connection_is_successful_please_wait...", nil)];
if (peripheral != self.peripheral) {
NSLog(@"Wrong Peripheral.\n");
return ;
}
if (error != nil) {
NSLog(@"Error %@\n", error);
return ;
}
{
for (CBCharacteristic * Characteristic in characteristics) {
NSLog(@"Characteristic.uuid----%@",Characteristic.UUID);
NSString * uuidStr = [NSString stringWithFormat:@"%@",Characteristic.UUID];
if ([uuidStr isEqualToString:@"FFE1"]) {
self.characteristic_read = Characteristic;
}else if ([uuidStr isEqualToString:@"FFE2"]){
self.characteristic_write = Characteristic;
}else if ([uuidStr isEqualToString:@"FFE4"]){
self.characteristic_powerNotify = Characteristic;
}
}
[self.peripheral setNotifyValue:YES forCharacteristic:self.characteristic_powerNotify];
[self.peripheral setNotifyValue:YES forCharacteristic:self.characteristic_read];
[self.peripheral setNotifyValue:YES forCharacteristic:self.characteristic_write];
#pragma mark 所有搜索,连接,寻找服务,找到characteristic通道的操作都已完成
/*---所有搜索,连接,寻找服务,找到characteristic通道的操作都已完成----*/
/*
做获取电量的操作
*/
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
unsigned char byte[] = {0xF8,0x01,0x00,0x02,0x01,0x00};//电量
NSData * theData = [NSData dataWithBytes:byte length:sizeof(byte)];
[self writeWithData:theData WithCharacteristic:self.characteristic_write];
});
}
}
8.向外设写入数据和获得会掉的方法
#pragma mark 向设备端写数据
//向设备写数据
- (void)writeWithData:(NSData *)data WithCharacteristic:(CBCharacteristic *)characterris{
}
#pragma mark 接收到设备端回调 处理数据,读到数据后会调用delegate方法:
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
}
9.字节数据处理
{
unsigned char byte[] = {0xF8,0x02,0x00};//头字节
NSData *first_Data = [NSData dataWithBytes:byte length:sizeof(byte)];
NSMutableData * lastData = [NSMutableData dataWithData:first_Data];
int Link_Long = 16;//整个应用层数据长度,包括功能符和应用层数据长度两个字节
NSData *Link_Long_Data = [NSData dataWithBytes:&Link_Long length:sizeof(Byte)];
[lastData appendData:Link_Long_Data];
unsigned char byte2[] = {0x02};//功能标示字节-写入md5
NSData *theData = [NSData dataWithBytes:byte2 length:sizeof(byte2)];
int Application_Long = 16;//应用层的数据长度(md5码的长度)
NSData *Application_Long_data = [NSData dataWithBytes:&Application_Long length:sizeof(Byte)];
[lastData appendData:Application_Long_data];
[self writeWithData:lastData WithCharacteristic:self.characteristic_write];
}