美文网首页iOS学习笔记
蓝牙连接以及发送数据

蓝牙连接以及发送数据

作者: 勇不言弃92 | 来源:发表于2017-03-29 09:57 被阅读48次

1.连接蓝牙的常规代码

1.首先引入库:#import <CoreBluetooth/CoreBluetooth.h>
2.代理:<CBCentralManagerDelegate,CBPeripheralDelegatea>
3.准备设备管理

//创建中心管理者,管理中心设备
self.mgr = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
[self cleanup];
//开始搜索蓝牙设备
[self.mgr scanForPeripheralsWithServices:nil options:nil];

4.代理方法--代码中有注释,特别注意代码中的“kServiceUUID,kCharacteristicUUID,SERVICE_UUID,CHAR_UUID这四个参数”

#pragma mark - 清理蓝牙
//清理缓存
- (void)cleanup
{

if (!self.myPeripheral) {
return;
}

if (self.myPeripheral.state==CBPeripheralStateDisconnected||self.myPeripheral.state == CBPeripheralStateConnecting)
{
self.myPeripheral=nil;
self.characteristic = nil;
return;
}

if (self.service != nil&&self.characteristic!=nil)
{
if (self.characteristic.isNotifying)
{
[self.myPeripheral setNotifyValue:NO forCharacteristic:self.characteristic];
}
}

[self.mgr cancelPeripheralConnection:self.myPeripheral];

[self.mgr stopScan];

self.myPeripheral=nil;
self.service=nil;
self.characteristic=nil;
}

#pragma mark - CBCentralManagerDelegate
//设备蓝牙状态更新
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{

switch (central.state) {
case CBCentralManagerStateUnsupported:
NSLog(@"该设备不支持BLE蓝牙");
break;
case CBCentralManagerStateUnauthorized:
NSLog(@"该设备未授权BLE蓝牙");
break;
case CBCentralManagerStatePoweredOff:
NSLog(@"该设备BLE蓝牙已关闭");
break;
case CBCentralManagerStateUnknown:
NSLog(@"该设备BLE蓝牙发生未知错误");
break;
case CBCentralManagerStateResetting:
NSLog(@"该设备BLE蓝牙重置中");
break;
case CBCentralManagerStatePoweredOn:
[self cleanup];
[self.mgr scanForPeripheralsWithServices:nil options:nil];
break;

default:
NSLog(@"Central Manager did change state");
break;
}
}

//发现外部设备时候调用此方法
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSString *periName = peripheral.name;

self.myPeripheral = peripheral;
//连接设备,这里是连接了所有设备,应该做的是跟据设备的已知信息去连接设备
[self.mgr connectPeripheral:self.myPeripheral options:nil];
//停止扫描蓝牙
[self.mgr stopScan];
}

//连接蓝牙成功
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
//发现服务
self.myPeripheral .delegate = self;
[self.myPeripheral  discoverServices:nil];
}

//连接蓝牙失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSString *err = [NSString stringWithFormat:@"连接蓝牙门禁%@失败,原因:%@",peripheral.name,[error localizedDescription]];
NSLog(@"%@",err);
}

//断开蓝牙连接
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
}


#pragma mark - CBPeripheralDelegate
//外设已经查找到服务
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
if (error) return; //发现服务失败

//遍历所有服务
for (CBService *service in self.myPeripheral.services) {
NSLog(@"%@",service.UUID);
if ([service.UUID isEqual:[CBUUID UUIDWithString:kServiceUUID]]){
self.service = service;
break;
}
}

if (self.service) {

[self.myPeripheral discoverCharacteristics:nil forService:self.service];
}

}

#pragma mark 找到特征时调用

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
if (error) return; //发现特征失败

for (CBCharacteristic *characteristic in self.service.characteristics)
{
NSLog(@"%@",characteristic.UUID);
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kCharacteristicUUID]])
{
self.characteristic = characteristic;
//对此特征设置通知和读取返回数据
[self.myPeripheral setNotifyValue:YES forCharacteristic:self.characteristic];
[self.myPeripheral readValueForCharacteristic:self.characteristic];
[self sendMessageToBle];
break;
}

}
}


- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (error) {
NSLog(@"%@",error);
return;
} //发送数据失败

}


- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (error) return; //接收特征数据失败
NSString *value = [[NSString alloc] initWithData:characteristic.value encoding:NSASCIIStringEncoding];
NSLog(@"value==============%@",value);//蓝牙返回的信息,需要对蓝牙设备做特殊处理才能按照一定的格式返回数据
if ([[value lowercaseString] isEqualToString:@"success"]){

}else if ([[value lowercaseString] isEqualToString:@"fail"]){

}
}

- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (error) return; //开启特征数据返回通知失败

}

2.iOS开发过程中没有直接获取蓝牙Mac地址的方法,需要从读取的数据中提出

参考MacPu的博客-iOS如果获取蓝牙Mac地址 谢谢!
将“kServiceUUID,kCharacteristicUUID“分别设置为“180A,2A23”,

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (error) return; //接收特征数据失败
NSString *value = [NSString stringWithFormat:@"%@",characteristic.value];
NSMutableString *macString = [[NSMutableString alloc] init];
[macString appendString:[[value substringWithRange:NSMakeRange(16, 2)] uppercaseString]];
[macString appendString:@":"];
[macString appendString:[[value substringWithRange:NSMakeRange(14, 2)] uppercaseString]];
[macString appendString:@":"];
[macString appendString:[[value substringWithRange:NSMakeRange(12, 2)] uppercaseString]];
[macString appendString:@":"];
[macString appendString:[[value substringWithRange:NSMakeRange(5, 2)] uppercaseString]];
[macString appendString:@":"];
[macString appendString:[[value substringWithRange:NSMakeRange(3, 2)] uppercaseString]];
[macString appendString:@":"];
[macString appendString:[[value substringWithRange:NSMakeRange(1, 2)] uppercaseString]];
NSLog(@"macString:%@",macString);
}

3.向蓝牙设备发送数据,并且接收返回数据

在我的实际操作中,发现每次向蓝牙发送数据的时候总是失败,需要借助下面的代码才能发送成功

#pragma mark - 向蓝牙发送数据
- (void)sendMessageToBle{
//加密数据
int index =  arc4random() % 20;
NSString *doorcode = self.doorArray[index];

NSString *dateStr1 = [NSDate stringFromDate:[NSDate date] withFormat:@"yyyyMMdd"];
NSString *dateStr2 = [NSDate stringFromDate:[NSDate date] withFormat:@"MMddyyyy"];
NSString *dateStr = [NSString stringWithFormat:@"%@%@",dateStr1,dateStr2];

NSString *strA1 = @"OW15LjrCaY2bfcMl";
NSString *strB1 = @"aWuK48JRDPePsYXE";

Byte *A = [self strToByte:dateStr];
Byte *A1 = [self strToByte:strA1];
Byte *B = [self strToByte:doorcode];
Byte *B1 = [self strToByte:strB1];

Byte bleData[16] = {0};
for (int i = 0; i < strA1.length; i ++) {
Byte left = (Byte)(A[i] & A1[i]);
Byte right = (Byte)(B[i] | B1[i]);
bleData[i] = (Byte)(left ^ right);
}
Byte bleMD5[16] ={0};
CC_MD5(bleData, 16, bleMD5);
Byte final[15] = {0};
final[0] = 15;
for (int i = 0; i < 12; i ++) {
final[i + 1] = bleMD5[i];
}
final[13] = 13;
final[14] = 10;

NSData *finalData = [NSData dataWithBytes:final length:15];

[self writeValue:SERVICE_UUID characteristicUUID:CHAR_UUID p:self.myPeripheral data:finalData];
}

-(void) writeValue:(int)serviceUUID characteristicUUID:(int)characteristicUUID p:(CBPeripheral *)p data:(NSData *)data {
//这里对服务值以及特征值做了一下处理,按照硬件的识别方式转换一下
UInt16 s = [self swap:serviceUUID];
UInt16 c = [self swap:characteristicUUID];
NSData *sd = [[NSData alloc] initWithBytes:(char *)&s length:2];
NSData *cd = [[NSData alloc] initWithBytes:(char *)&c length:2];
CBUUID *su = [CBUUID UUIDWithData:sd];
CBUUID *cu = [CBUUID UUIDWithData:cd];
CBService *service = [self findServiceFromUUIDEx:su p:p];
if (!service) {
printf("Could not find service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:su],[self UUIDToString:(__bridge CFUUIDRef )p.identifier]);
return;
}
CBCharacteristic *characteristic = [self findCharacteristicFromUUIDEx:cu service:service];
if (!characteristic) {
printf("Could not find characteristic with UUID %s on service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:cu],[self CBUUIDToString:su],[self UUIDToString:(__bridge CFUUIDRef )p.identifier]);
return;
}
[p setNotifyValue:YES forCharacteristic:characteristic];
//写入数据时选择有返回数据/无返回数据
if(characteristic.properties & CBCharacteristicPropertyWriteWithoutResponse)
{
[p writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
}else
{
[p writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
}

-(UInt16) swap:(UInt16)s {
UInt16 temp = s << 8;
temp |= (s >> 8);
return temp;
}
-(CBService *) findServiceFromUUIDEx:(CBUUID *)UUID p:(CBPeripheral *)p {
for(int i = 0; i < p.services.count; i++) {
CBService *s = [p.services objectAtIndex:i];
if ([self compareCBUUID:s.UUID UUID2:UUID]) return s;
}
return nil; //Service not found on this peripheral
}
-(int) compareCBUUID:(CBUUID *) UUID1 UUID2:(CBUUID *)UUID2 {
char b1[16];
char b2[16];
[UUID1.data getBytes:b1];
[UUID2.data getBytes:b2];
if (memcmp(b1, b2, UUID1.data.length) == 0)return 1;
else return 0;
}
-(const char *) CBUUIDToString:(CBUUID *) UUID {
return [[UUID.data description] cStringUsingEncoding:NSStringEncodingConversionAllowLossy];
}
-(const char *) UUIDToString:(CFUUIDRef)UUID {
if (!UUID) return "NULL";
CFStringRef s = CFUUIDCreateString(NULL, UUID);
return CFStringGetCStringPtr(s, 0);
}

-(CBCharacteristic *) findCharacteristicFromUUIDEx:(CBUUID *)UUID service:(CBService*)service {
for(int i=0; i < service.characteristics.count; i++) {
CBCharacteristic *c = [service.characteristics objectAtIndex:i];
if ([self compareCBUUID:c.UUID UUID2:UUID]) return c;
}
return nil; //Characteristic not found on this service
}

//字符串转byte
- (Byte *)strToByte:(NSString *)strBefor{
Byte *bt = (Byte *)malloc(16);
for (int i =0; i < strBefor.length; i++) {
int strInt = [strBefor characterAtIndex:i];
Byte b =  (Byte) ((0xff & strInt) );//( Byte) 0xff&iByte;
bt[i] = b;
}
return bt;
}

直戳demo源码

相关文章

  • 蓝牙连接以及发送数据

    1.连接蓝牙的常规代码 1.首先引入库:#import

  • Android BLE蓝牙详细解读(一)

    本文主要讲解Android低功耗蓝牙的api使用以及蓝牙扫描、连接、发送数据、接收数据等一系列操作,本篇结尾有本人...

  • 03.BLE数据处理之项目总结(二)

    前面的蓝牙连接,这里就不再讲解了,直接从连接成功后,初始化发送指令给蓝牙说起;项目中,蓝牙连接是进行了封装的,数据...

  • 蓝牙连接

    1.蓝牙搜索 2.蓝牙连接 3.注册收发数据的通知 **##4.发送数据 5.接收数据 下载Demo--> 我的g...

  • iOS蓝牙开发

    iOS的蓝牙数据接收以及发送 名词:Central(中心设备)、Peripheral(外围设备)、advertis...

  • cordova-plugin-bluetooth-serial插

    连接蓝牙获取数据,具体的使用场景是用该插件连接蓝牙秤,然后获取蓝牙秤上面的重量值,在使用该插件的过程中遇到问题以及...

  • Android BLE 连接及数据传输详解

    本文将展开对蓝牙低功耗从扫描蓝牙设备,建立连接到蓝牙数据通信的详细介绍,以及详细介绍GATT Profile(Ge...

  • 蓝牙连接以及协议数据解析

    1.声明属性以及引入相关库 NSMutableArray *pers;//这个必须有,用于记录搜索到的设备,没有导...

  • Android 蓝牙搜索,配对,连接发送数据

    首先需要在清单配置里面添加两个权限: android里面蓝牙是通过BluetoothAdapter来进行操作的,所...

  • iOS 蓝牙开发

    前言:此篇文章只针对第一次接触蓝牙的小白,文章中仅仅描述了如何连接蓝牙、如何发送数据 、可能遇到的问题 等。对于其...

网友评论

    本文标题:蓝牙连接以及发送数据

    本文链接:https://www.haomeiwen.com/subject/iukeottx.html