#import "ViewController.h" #import <CoreBluetooth/CoreBluetooth.h> @interface ViewController ()<CBCentralManagerDelegate,CBPeripheralDelegate> /// 中央管理者 -->管理设备的扫描 --连接 @property (nonatomic, strong) CBCentralManager *centralManager; // 存储的设备 @property (nonatomic, strong) NSMutableArray *peripherals; // 扫描到的设备 @property (nonatomic, strong) CBPeripheral *cbPeripheral; // 文本 @property (weak, nonatomic) IBOutlet UITextView *peripheralText; // 蓝牙状态 @property (nonatomic, assign) CBManagerState peripheralState; @end // 蓝牙4.0设备名 static NSString * const kBlePeripheralName = @"apple"; // 通知服务 static NSString * const kNotifyServerUUID = @"FFE0"; // 写服务 static NSString * const kWriteServerUUID = @"FFE1"; // 通知特征值 static NSString * const kNotifyCharacteristicUUID = @"FFE2"; // 写特征值 static NSString * const kWriteCharacteristicUUID = @"FFE1"; @implementation ViewController - (NSMutableArray *)peripherals { if (!_peripherals) { _peripherals = [NSMutableArray array]; } return _peripherals; } - (CBCentralManager *)centralManager { if (!_centralManager) { _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; } return _centralManager; } // 222 扫描设备 - (IBAction)scanForPeripherals { [self.centralManager stopScan]; NSLog(@"扫描设备"); [self showMessage:@"扫描设备"]; if (self.peripheralState == CBManagerStatePoweredOn) { [self.centralManager scanForPeripheralsWithServices:nil options:nil]; } } // 连接设备 - (IBAction)connectToPeripheral { if (self.cbPeripheral != nil) { NSLog(@"连接设备"); [self showMessage:@"连接设备"]; [self.centralManager connectPeripheral:self.cbPeripheral options:nil]; } else { [self showMessage:@"无设备可连接"]; } } // 清空设备 - (IBAction)clearPeripherals { NSLog(@"清空设备"); [self.peripherals removeAllObjects]; self.peripheralText.text = @""; [self showMessage:@"清空设备"]; if (self.cbPeripheral != nil) { // 取消连接 NSLog(@"取消连接"); [self showMessage:@"取消连接"]; [self.centralManager cancelPeripheralConnection:self.cbPeripheral]; } } //000 - (void)viewDidLoad { [super viewDidLoad]; [self centralManager]; } ///111 //只要中心管理者初始化 就会触发此代理方法 判断手机蓝牙状态 状态更新时调用 - (void)centralManagerDidUpdateState:(CBCentralManager *)central { switch (central.state) { case CBManagerStateUnknown:{ NSLog(@"为知状态"); self.peripheralState = central.state; } break; case CBManagerStateResetting: { NSLog(@"重置状态"); self.peripheralState = central.state; } break; case CBManagerStateUnsupported: { NSLog(@"不支持的状态"); self.peripheralState = central.state; } break; case CBManagerStateUnauthorized: { NSLog(@"未授权的状态"); self.peripheralState = central.state; } break; case CBManagerStatePoweredOff: { NSLog(@"关闭状态"); self.peripheralState = central.state; } break; case CBManagerStatePoweredOn: { NSLog(@"开启状态-可用状态"); self.peripheralState = central.state; // 链接成功开始扫描设备 [self scanForPeripherals]; NSLog(@"%ld",(long)self.peripheralState); } break; default: break; } } /** 333扫描到设备 发现设备是开启状态后调用方法 @param central 中心管理者 @param peripheral 扫描到的设备 @param advertisementData 广告信息 @param RSSI 信号强度 */ - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI { [self showMessage:[NSString stringWithFormat:@"发现设备,设备名:%@",peripheral.name]]; // 设备数组中是否存在 该设备 if (![self.peripherals containsObject:peripheral]) { [self.peripherals addObject:peripheral]; NSLog(@"%@",peripheral); [self showMessage:[NSString stringWithFormat:@"设备名:%@",peripheral.name]]; //最常用的场景是查找某一个前缀开头的设备 // if ([peripheral.name hasPrefix:@"JDY"] ) { [self showMessage:@"开始连接"]; [self.centralManager connectPeripheral:peripheral options:nil]; // } } } /** 连接失败 @param central 中心管理者 @param peripheral 连接失败的设备 @param error 错误信息 */ - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error { [self showMessage:@"连接失败"]; if ([peripheral.name isEqualToString:kBlePeripheralName]) { [self.centralManager connectPeripheral:peripheral options:nil]; } } /** 连接断开 @param central 中心管理者 @param peripheral 连接断开的设备 @param error 错误信息 */ - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error { [self showMessage:@"断开连接"]; if ([peripheral.name isEqualToString:kBlePeripheralName]) { [self.centralManager connectPeripheral:peripheral options:nil]; } } /** 444连接成功 @param central 中心管理者 @param peripheral 连接成功的设备 */ - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral { NSLog(@"连接设备:%@成功",peripheral.name); // self.peripheralText.text = [NSString stringWithFormat:@"连接设备:%@成功",peripheral.name]; [self showMessage:[NSString stringWithFormat:@"连接设备:%@成功",peripheral.name]]; // 设备 self.cbPeripheral = peripheral; // 设置设备的代理 peripheral.delegate = self; // services:传入nil 代表扫描所有服务 [peripheral discoverServices:nil]; } /** 555扫描到服务 @param peripheral 服务对应的设备 @param error 扫描错误信息 */ - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error { // 遍历所有的服务 for (CBService *service in peripheral.services) { NSLog(@"服务:%@",service.UUID.UUIDString); // 获取对应的服务 if ([service.UUID.UUIDString isEqualToString:kWriteServerUUID] || [service.UUID.UUIDString isEqualToString:kNotifyServerUUID]) { // 根据服务去扫描特征 [peripheral discoverCharacteristics:nil forService:service]; } } } /** 666扫描到对应的特征 @param peripheral 设备 @param service 特征对应的服务 @param error 错误信息 */ - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error { // 遍历所有的特征 for (CBCharacteristic *characteristic in service.characteristics) { NSLog(@"特征值:%@",characteristic.UUID.UUIDString); if ([characteristic.UUID.UUIDString isEqualToString:kNotifyCharacteristicUUID]) { // 写入数据 M_1_1000_ NSString *testString = [NSString stringWithFormat:@"%@",@"M_1_1000_ "]; NSData *data = [testString dataUsingEncoding: NSUTF8StringEncoding]; // NSData *data = [self hexToBytes:testString]; // Byte byte[] = {0xf0, 0x3d, 0x3d, 0x5d,0x02,0xf7}; // NSData *data = [NSData dataWithBytes:byte length:6]; [self.cbPeripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse]; [self showMessage:@"写入特征值"]; // for (Byte i = 0x0; i < 0x73; i++) // { // Byte byte[] = {0xf0, 0x3d, 0x3d, i, // 0x02,0xf7}; // NSData *data = [NSData dataWithBytes:byte length:6]; // [peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse]; // } } if ([characteristic.UUID.UUIDString isEqualToString:kNotifyCharacteristicUUID]) { [peripheral setNotifyValue:YES forCharacteristic:characteristic]; } } } - (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error; { //这个方法比较好,这个是你发数据到外设的某一个特征值上面,并且响应的类型是 CBCharacteristicWriteWithResponse ,上面的官方文档也有,如果确定发送到外设了,就会给你一个回应,当然,这个也是要看外设那边的特征值UUID的属性是怎么设置的,看官方文档,人家已经说了,条件是,特征值UUID的属性:CBCharacteristicWriteWithResponse if (!error) { NSLog(@"说明发送成功,characteristic.uuid为:%@ 发送为%@",[characteristic.UUID UUIDString],characteristic.value); Byte byte2[] = {0xf0, 0x3d, 0x3d, 0x5d,0x02,0xf7}; NSData* data2 = [[NSData alloc] initWithBytes:byte2 length:3]; if ([characteristic.value isEqualToData:data2]) { NSLog(@"说明发送成功,characteristic.uuid为:%@ 发送为%@",[characteristic.UUID UUIDString],characteristic.value); } }else{ NSLog(@"发送失败了啊!characteristic.uuid为:%@ 原因:%@",[characteristic.UUID UUIDString],error); } //调用下面的方法后 会调用到代理的- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error [peripheral readValueForCharacteristic:characteristic]; } /** 根据特征读到数据 @param peripheral 读取到数据对应的设备 @param characteristic 特征 @param error 错误信息 */ - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullable NSError *)error { if ([characteristic.UUID.UUIDString isEqualToString:kNotifyCharacteristicUUID]) { NSData *data = characteristic.value; NSLog(@"%@",data); // 2017-04-25 12:34:41.876974+0800 蓝牙4.0Demo[1745:346611] <9f5436> // 2017-04-25 12:34:41.983016+0800 蓝牙4.0Demo[1745:346611] <8f5440> // 2017-04-25 12:34:42.154821+0800 蓝牙4.0Demo[1745:346611] <9f5649> // 2017-04-25 12:34:42.239481+0800 蓝牙4.0Demo[1745:346611] <8f5640> } } - (void)showMessage:(NSString *)message { self.peripheralText.text = [self.peripheralText.text stringByAppendingFormat:@"%@ ",message]; [self.peripheralText scrollRectToVisible:CGRectMake(0, self.peripheralText.contentSize.height -15, self.peripheralText.contentSize.width, 10) animated:YES]; } // 把string类型转成byte 之后转成data -(NSData*)hexToBytes:(NSString *)string{ NSMutableData* data = [[NSMutableData alloc]init]; int idx; for (idx = 0; idx+2 <= string.length; idx +=2) { NSRange range = NSMakeRange(idx, 2); NSString* hexStr = [string substringWithRange:range]; NSScanner* scanner = [NSScanner scannerWithString:hexStr]; unsigned int intValue; [scanner scanHexInt:&intValue]; [data appendBytes:&intValue length:1]; } return data; } //data转string - (NSString *)hexStringFromData:(NSData*)data{ return [[[[NSString stringWithFormat:@"%@",data] stringByReplacingOccurrencesOfString: @"<" withString: @""] stringByReplacingOccurrencesOfString: @">" withString: @""] stringByReplacingOccurrencesOfString: @" " withString: @""]; } @end