首先导入库#import
遵循代理:
声明变量:
@property(nonatomic,strong)CBCentralManager*bluetoothManager;
@property(nonatomic,strong)CBPeripheralManager*manager;
1、创建中心设备并设置代理:
self.bluetoothManager=[[CBCentralManageralloc]initWithDelegate:self queue:dispatch_get_main_queue()];
self.manager=[[CBPeripheralManageralloc]initWithDelegate:self queue:nil];
CBCentralManagerDelegate代理必须执行方法是查看中心设备状态是否打开蓝牙:
-(void)centralManagerDidUpdateState:(CBCentralManager
*)central{
switch (central.state) {
case CBCentralManagerStateUnknown:
break;
case CBCentralManagerStateResetting:
break;
case CBCentralManagerStateUnsupported:
break;
case CBCentralManagerStateUnauthorized:
break;
case CBCentralManagerStatePoweredOff:
break;
case CBCentralManagerStatePoweredOn:
break;
default:
break;
}
}
2、开始扫描外部设备:
[self.bluetoothManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @NO }];
第一个参数那里表示扫描带有相关服务的外部设备,例如填写
@[[CBUUID UUIDWithString:@"需要连接的外部设备的服务的UUID"]],即表示带有需要连接的外部设备的服务的UUID的外部设备,nil表示扫描全部设备;
@{ CBCentralManagerScanOptionAllowDuplicatesKey : @NO }
NO表示不会让中心设备不断地监听外部设备的消息,YES就是能不断地监听外部设备消息。
3、一旦扫描到外部设备,就会进入协议中:
-(void)centralManager:(CBCentralManager *)centraldidDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{
//找到的设备必须持有它,否则CBCentralManager中也不会保存peripheral,那么CBPeripheralDelegate中的方法也不会被调用!
在这里可以根据我们所知道的硬件设备条件来筛选所需要的设备,将其他打开蓝牙的设备排除在外。
例如:搜找硬件盒子名字为JL的设备:
@property (nonatomic, strong) NSMutableArray *peripherals;
@property(nonatomic, strong) NSMutableArray *peripheralsNameArray;
初始化数组略
if (! [self.peripherals containsObject:peripheral]) {
[self.peripherals addObject:peripheral];
}
NSArray *tempPeripherals = [self.peripheralscopy];
for (CBPeripheral *per intempPeripherals) {
if (! [self.peripheralsNameArraycontainsObject:per.name]){
if ([[per.name substringToIndex:2]isEqualToString:@"JL"]) {
[self.peripheralsNameArrayaddObject:per.name];
}else {
[self.peripherals removeObject:per];
}
}
}
}
选择某一搜索到的特定设备进行连接:
LGAlertView *alert= [LGAlertView alertViewWithTitle:@"请选择您的设备"
message:@"" style:LGAlertViewStyleActionSheet buttonTitles:self.peripheralsNameArray
cancelButtonTitle:@"取消"destructiveButtonTitle:nil actionHandler:^(LGAlertView *alertView, NSString*title, NSUInteger index) {
CBPeripheral *per;
per = index
self.deviceName = index
[self.bluetoothManagerconnectPeripheral:per options:nil];
此时是中心设备和外部设备的连接,连接成功或者失败会进入不同的方法。
} cancelHandler:^(LGAlertView*alertView) {
[self.bluetoothManagerstopScan];
} destructiveHandler:nil];
}
4、中心设备与外部设备连接状态调用的方法:
-(void)centralManager:(CBCentralManager *)centraldidConnectPeripheral:(CBPeripheral *)peripheral(中心设备和外部设备的连接成功){
[central stopScan];
//设置的peripheral委托CBPeripheralDelegate
[peripheral setDelegate:self];
//扫描外设Services,成功后会进入方法:
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError*)error;
[peripheral discoverServices:nil];
}
- (void)centralManager:(CBCentralManager *)central
didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullableNSError
*)error;(中心设备和外部设备的连接断开)
- (void)centralManager:(CBCentralManager *)central
didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error ;(中心设备和外部设备的连接,连接失败)
5、扫描外设服务后紧接着会进入服务的代理方法中:
- (void)peripheral:(CBPeripheral *)peripheraldidDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
for (CBService *service inperipheral.services) {
//扫描每个service的Characteristics,扫描到后会进入方法:-(void)peripheral:(CBPeripheral *)peripheral
didDiscoverCharacteristicsForService:(CBService *)service error:(NSError
*)error;
[peripheral discoverCharacteristics:nilforService:service];
}
}
- (void)peripheral:(CBPeripheral *)peripheraldidDiscoverCharacteristicsForService:(CBService *)service error:(NSError*)error{
//获取Characteristic的值,读到数据会进入方法:-(void)peripheral:(CBPeripheral
*)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic
error:(NSError *)error;
for (CBCharacteristic*characteristic in service.characteristics){
[peripheralreadValueForCharacteristic:characteristic];
}
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic*)characteristic error:(NSError *)error {
//打印出characteristic的UUID和值
//!注意,value的类型是NSData,具体开发时,会根据外设协议制定的方式去解析数据
NSLog(@"characteristicuuid:%@value:%@",characteristic.UUID,characteristic.value);
}
6、根据拿到的数据就可以进行写操作:
//写数据
- (void)writeCharacteristic:(CBPeripheral *)peripheral characteristic:(CBCharacteristic*)characteristic value:(NSData *)value {
//打印出characteristic的权限,可以看到有很多种,这是一个NS_OPTIONS,就是可以同时用于好几个值,常见的有read,write,notify,indicate,知道这几个基本就够用了,前连个是读写权限,后两个都是通知,两种不同的通知方式。
/*
typedef NS_OPTIONS(NSUInteger,CBCharacteristicProperties) {
CBCharacteristicPropertyBroadcast= 0x01,
CBCharacteristicPropertyRead= 0x02,
CBCharacteristicPropertyWriteWithoutResponse= 0x04,
CBCharacteristicPropertyWrite= 0x08,
CBCharacteristicPropertyNotify= 0x10,
CBCharacteristicPropertyIndicate= 0x20,
CBCharacteristicPropertyAuthenticatedSignedWrites= 0x40,
CBCharacteristicPropertyExtendedProperties= 0x80,
CBCharacteristicPropertyNotifyEncryptionRequired NS_ENUM_AVAILABLE(NA,6_0)= 0x100,
CBCharacteristicPropertyIndicateEncryptionRequired NS_ENUM_AVAILABLE(NA,6_0)= 0x200
};
*/
//只有characteristic.properties有write的权限才可以写
if(characteristic.properties& CBCharacteristicPropertyWrite){
//最好一个type参数可以为CBCharacteristicWriteWithResponse或type:CBCharacteristicWriteWithResponse,区别是是否会有反馈
[peripheral writeValue:valueforCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
}
7、根据下面方法判断写入成功与否:
- (void)peripheral:(CBPeripheral *)peripheraldidWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError*)error;
8、搜索Characteristic的Descriptors,读到数据会进入方法:
-(void)peripheral:(CBPeripheral *)peripheraldidDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristicerror:(NSError *)error{
for (CBCharacteristic*characteristic in service.characteristics){
[peripheraldiscoverDescriptorsForCharacteristic:characteristic];
}
}
//搜索到Characteristic的Descriptors
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic*)characteristic error:(NSError *)error
//获取到Descriptors的值
- (void)peripheral:(CBPeripheral *)peripheraldidUpdateValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error {
//打印出DescriptorsUUID和value
//这个descriptor都是对于characteristic的描述,一般都是字符串,所以这里我们转换成字符串去解析
NSLog(@"characteristicuuid:%@value:%@",[NSStringstringWithFormat:@"%@",descriptor.UUID],descriptor.value);
}
9、停止并断开连接设备:
- (void)disconnectPeripheral:(CBCentralManager *)centralManagerperipheral:(CBPeripheral *)peripheral {
//停止扫描
[centralManager stopScan];
//断开连接
[centralManagercancelPeripheralConnection:peripheral];
}