实现细节
//建立中心角色—扫描外设(discover)—连接外设(connect)—扫描外设中的服务和特征(discover)—与外设做数据交互(explore and interact)—断开连接(disconnect)。
//开始查看服务, 蓝牙开启
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
switch (central.state) {
case CBCentralManagerStatePoweredOn:
NSLog(@"蓝牙已打开, 请扫描外设!");
break;
default:
break;
}
}
1建立中心角色
//头文件中要包含CoreBluetooth的头文件,并继承两个协议<CBCentralManagerDelegate,CBPeripheralDelegate>
#import <CoreBluetooth/CoreBluetooth.h>
CBCentralManager* myCentralManager;
myCentralManager = [[CBCentralManager alloc]initWithDelegate:self queue:nil options:nil];
2扫描外设(discover)
//_myPeripheral: 外设
[self.myCentralManager scanForPeripheralsWithServices:nil options:nil];
if(_myPeripheral != nil){
[_myCentralManager cancelPeripheralConnection:_myPeripheral];
}
//设置延迟时间
double delayInSeconds = 60.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds* NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self.myCentralManager stopScan];
NSLog(@"扫描超时,停止扫描!");
});
//设置指定UUID
NSArray *uuidArray = [NSArray arrayWithObjects:[CBUUID UUIDWithString:@"1800"],[CBUUID UUIDWithString:@"180A"],
[CBUUID UUIDWithString:@"1CB2D155-33A0-EC21-6011-CD4B50710777"],[CBUUID UUIDWithString:@"6765D311-DD4C-9C14-74E1-A431BBFD0652"],nil];
[manager scanForPeripheralsWithServices:uuidArray options:options];
//查到外设后自动返回peripherals
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{
NSLog(@"已发现 peripheral: %@ rssi: %@, uuid: %@ advertisementData: %@", peripheral, RSSI, peripheral.UUID, advertisementData);
[_myPeripherals addObject:peripheral];
NSInteger count = [_myPeripherals count];
NSLog(@"my periphearls count : %ld\n", (long)count);
}
3连接外设(connect)
//连接外设
[self.myCentralManager connectPeripheral:self.myPeripheral options:nil];
//连接外设成功
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
// NSLog(@"成功连接 peripheral: %@ with UUID: %@",peripheral, peripheral.UUID);
[self.myPeripheral setDelegate:self];
[self.myPeripheral discoverServices:nil];
NSLog(@"扫描服务...");
[_peripheralState setText:@"connected"];
[_attention setText:@""];
}
//掉线时调用
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
NSLog(@"periheral has disconnect");
[_peripheralState setText:@"disconnected"];
}
//连接外设失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
NSLog(@"%@", error);
[_peripheralState setText:@"disconnected"];
}
4扫描外设中的服务和特征(discover)
//同样的,当连接成功后,系统会通过回调函数告诉我们,然后我们就在这个回调里去扫描设备下所有的服务和特征:
//在连接外设成功中添加
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
// NSLog(@"成功连接 peripheral: %@ with UUID: %@",peripheral, peripheral.UUID);
[self.myPeripheral setDelegate:self];
[self.myPeripheral discoverServices:nil]; //##
NSLog(@"扫描服务...");
}
//已发现服务
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
NSLog(@"发现服务!");
int i = 0;
for(CBService* s in peripheral.services){
[self.nServices addObject:s];
}
for(CBService* s in peripheral.services){
NSLog(@"%d :服务 UUID: %@(%@)", i, s.UUID.data, s.UUID);
i++;
[peripheral discoverCharacteristics:nil forService:s];
NSLog(@"扫描Characteristics...");
}
}
//已发现characteristcs
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
for(CBCharacteristic* c in service.characteristics){
NSLog(@"特征 UUID: %@ (%@)", c.UUID.data, c.UUID);
if([c.UUID isEqual:[CBUUID UUIDWithString:@"FFF2"]]){
self.writeCharacteristic = c;
NSLog(@"找到WRITE : %@", c);
}else if([c.UUID isEqual:[CBUUID UUIDWithString:@"FFF1"]]){
self.readCharacteristic = c;
[self.myPeripheral setNotifyValue:YES forCharacteristic:c];
[self.myPeripheral readValueForCharacteristic:c];
}
}
}
5与外设做数据交互(explore and interact)
//启动侦听,准备读取Peripheral的数据,连接成功时调用
[self.myPeripheral setNotifyValue:YES forCharacteristic:c]
[self.myPeripheral readValueForCharacteristic:c];
//中心读取外设实时数据:特征值被更新时触发
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
if(error){
NSLog(@"Error changing notification state: %@", error.localizedDescription);
}
//Notification has started
if(characteristic.isNotifying){
[peripheral readValueForCharacteristic:characteristic];
}else{
NSLog(@"Notification stopped on %@. Disconnting", characteristic);
[self.myCentralManager cancelPeripheralConnection:self.myPeripheral];
}
}
//周边发送新的值,获取外设发来的数据,不论是read和notify,获取数据都从这个方法中读取
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
[peripheral readRSSI];
NSNumber* rssi = [peripheral RSSI];
[_peripheralRssi setText:[NSString stringWithFormat:@"%@", rssi]];
if([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"FFF1"]]){
NSData* data = characteristic.value;
NSString* value = [self hexadecimalString:data];
NSLog(@"characteristic : %@, data : %@, value : %@", characteristic, data, value);
}
}
//向peripheral中写入数据
- (void)writeToPeripheral:(NSString *)data{
if(!_writeCharacteristic){
NSLog(@"writeCharacteristic is nil!");
return;
}
NSData* value = [self dataWithHexstring:data];
[_myPeripheral writeValue:value forCharacteristic:_writeCharacteristic type:CBCharacteristicWriteWithResponse];
}
//向peripheral中写入数据后的回调函数
- (void)peripheral:(CBPeripheral*)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
NSLog(@"write value success : %@", characteristic);
}
6数据类型转换
//将传入的NSData类型转换成NSString并返回
- (NSString*)hexadecimalString:(NSData *)data{
NSString* result;
const unsigned char* dataBuffer = (const unsigned char*)[data bytes];
if(!dataBuffer){
return nil;
}
NSUInteger dataLength = [data length];
NSMutableString* hexString = [NSMutableString stringWithCapacity:(dataLength * 2)];
for(int i = 0; i < dataLength; i++){
[hexString appendString:[NSString stringWithFormat:@"%02lx", (unsigned long)dataBuffer[i]]];
}
result = [NSString stringWithString:hexString];
return result;
}
//将传入的NSString类型转换成NSData并返回
- (NSData*)dataWithHexstring:(NSString *)hexstring{
NSMutableData* data = [NSMutableData data];
int idx;
for(idx = 0; idx + 2 <= hexstring.length; idx += 2){
NSRange range = NSMakeRange(idx, 2);
NSString* hexStr = [hexstring substringWithRange:range];
NSScanner* scanner = [NSScanner scannerWithString:hexStr];
unsigned int intValue;
[scanner scanHexInt:&intValue];
[data appendBytes:&intValue length:1];
}
return data;
}
7 断开连接(disconnect)
[self.myCentralManager cancelPeripheralConnection:self.myPeripheral];