iOS关于蓝牙框架BLE的开发--基础用法(下)

承接上文:iOS关于蓝牙框架BLE的开发--基础用法(上)
上文提及到对特征码CBCharacteristic进行操作,现在聊聊对应不同的操作的后续吧...

操作特征码后的回调——订阅/读取回调与失败回调

1.订阅/读取成功

按正常流程,通过特征码的订阅或读取,成功之后,都会通过这个方法获取对应的数据:
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
其中characteristic.value就是订阅/读取特征码对应的数据,我们可以通过代理或者block把这个value传到需要用到的地方,全部代码如下:
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
if (error) {
NSLog(@"error:%s,%@",PRETTY_FUNCTION,error);
return;
}
else {
NSLog(@"peripheral value == %@",characteristic.value);
if (_delegate && [_delegate respondsToSelector:@selector(receiveData:data:)]) {
[_delegate receiveData:peripheral data:characteristic.value];
}
}
}

而大家看到,如果订阅/读取失败的话,就有error,所以我在这个方法判断一下error是否存在,如果存在就做相应的事情并且返回;

2.向设备写入数据或发送指令回调

当需求需要中心设备向外设写入数据或发送指令,如果使用的方法是CBCharacteristicWriteWithResponse的话,就会进入-(void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error这个代理方法里面去:

-(void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
  if (error) {
    NSLog(@"写入命令失败=====%@",error.userInfo);
  }
  else{
    NSLog(@"写入命令成功");
  }
}

再略略展开一下讲讲,一般有几种情况会用到写入方法,已经遇到过的情况先列举一下,日后可能还会增加

  • 有些外设,在获取数据前会让中心设备先在规定时间内发送认证指令,增加安全性.这样的话,我们订阅或读取特征码的方法,就要放到这个方法里面来了;
  • 有些外设,有一些例如同步时间啊,打开/关闭某个功能开关,修改设备名或者修改某个功能.这个时候,我们就要对不同的需求在这个地方做不同的操作,一般情况下,就写个代理或者block在其他地方实现.

3.读取外设信号

这点算是补充说明吧,在旧的iOS版本下,设备peripheral有个属性叫做RSSI,可以拿到外设的信号,而新的(忘记了在哪个)版本下,这个属性被废弃了,想要获取,就要通过[peripheral ReadRSSI]的方法来获取,执行这个方法后,将进入-(void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(NSError *)error这个代理方法,流程就和订阅和写入回调一样,就不详细讲了,不过这个方法,好像不用连接外设,只要搜索到了就可以用了

-(void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(NSError *)error{
  if (_delegate && [_delegate respondsToSelector:@selector(SG_readPeripheralRSSI:peripheral: error:)]) {
     [_delegate SG_readPeripheralRSSI:RSSI peripheral:peripheral error:error];
  }
}
一些补充
  • 苹果的框架下,没有提供方法让我们拿到外设的MAC地址的.但是,我们通过和硬件工程师的协商,把MAC地址暴露出来,就可以获取得到,而方法却比较苛刻.
    在iOS关于蓝牙框架BLE的开发--基础用法(上)搜索外设的步骤中,代理方法-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI有个很奇怪的东西混了进来,名字叫advertisementData,仔细一看,是个字典,而苹果是允许外设在成功连接前把要广播的数据存在这里,而通过指定keykCBAdvDataManufacturerData,在没连接成功的情况下获取里面包的内容,于是,我们就可以把MAC地址放进去,让我们中心设备拿到MAC地址了,我遇到的情况,就是要通过这个MAC地址和一些指定协议,来生成认证指令,发送到外设去;

  • 一般情况下,如果不过滤的话,搜索后蓝牙列表会有很多奇奇怪怪的设备,于是,我们会通过 advertisementData 这个广播包或者设备名字来进行过滤,把一些APP不需要展示的外设过滤掉,或者根据不同的名字和型号,兼容不同的设备并对其做不一样的操作.

  • 在我的具体项目,认证指令需要通过异或计算,把十六进制数据异或之后生成一个校验,什么是异或计算,怎么异或计算,本人也是直接谷歌的,就直接上代码吧:
    .h文件:
    #import

    @interface ExclusiveOr : NSObject
    /**
     添加数组
     */
    +(NSString *)exclusiveOrArray:(NSArray *)array;
    /**
     两个数进行异或
     */
    +(NSString *)pinxCreator:(NSString *)pan withPinv:(NSString *)pinv;
    @end
    

.m文件:

#import "ExclusiveOr.h"
#include 
#include 
#include 
@implementation ExclusiveOr

+(NSString *)exclusiveOrArray:(NSArray *)exclusive{
  if (exclusive.count !=0) {
    NSString *exclusiveString = exclusive.lastObject;
    for (int i =0; i= '0' && tempChar <='9') {
         return tempChar - '0';
  }
  else if (tempChar >= 'A' && tempChar <= 'F') {
    return tempChar - 'A' + 10;
  }
  return 0;
}
@end

到这里,我们对BLE开发基本就讲完了,或许后面,我会把一些简单的操作,如自动重连,刷新蓝牙列表,绑定设备之类的功能简单实现,骚骚期待一下吧...

Demo在想要不要发出来好...没人看就算了

你可能感兴趣的:(iOS关于蓝牙框架BLE的开发--基础用法(下))