美文网首页
iOS关于蓝牙框架BLE的开发--基础用法(下)

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

作者: 左眼见到肠 | 来源:发表于2017-03-29 11:25 被阅读290次

承接上文: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<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI有个很奇怪的东西混了进来,名字叫advertisementData,仔细一看,是个字典,而苹果是允许外设在成功连接前把要广播的数据存在这里,而通过指定keykCBAdvDataManufacturerData,在没连接成功的情况下获取里面包的内容,于是,我们就可以把MAC地址放进去,让我们中心设备拿到MAC地址了,我遇到的情况,就是要通过这个MAC地址和一些指定协议,来生成认证指令,发送到外设去;

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

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

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

.m文件:

#import "ExclusiveOr.h"
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
@implementation ExclusiveOr

+(NSString *)exclusiveOrArray:(NSArray *)exclusive{
  if (exclusive.count !=0) {
    NSString *exclusiveString = exclusive.lastObject;
    for (int i =0; i<exclusive.count - 1; i++) {
      if (i==0) {
            NSString *pan = [exclusive[i] uppercaseString];
            NSString *pinv = [exclusive[i+1] uppercaseString];
            exclusiveString = [ExclusiveOr pinxCreator:pan withPinv:pinv];
      }
      else{
        NSString *pinv = [exclusive[i+1] uppercaseString];
        exclusiveString = [ExclusiveOr pinxCreator:exclusiveString withPinv:pinv];
      }
    }
    return exclusiveString;
  }
  else{
    return @"";
  }
}

+ (NSString *)pinxCreator:(NSString *)pan withPinv:(NSString *)pinv  {
  if (pan.length != pinv.length)   {
      return nil;
  }
  const char *panchar = [pan UTF8String];
  const char *pinvchar = [pinv UTF8String];
  NSString *temp = [[NSString alloc] init];
  for (int i = 0; i < pan.length; i++) {
    int panValue = [ExclusiveOr charToint:panchar[i]];
    int pinvValue = [ExclusiveOr charToint:pinvchar[i]];
    temp = [temp stringByAppendingString:[NSString stringWithFormat:@"%X",panValue^pinvValue]];
      }
    return temp;
  }

+ (int)charToint:(char)tempChar {
  if (tempChar >= '0' && tempChar <='9') {
         return tempChar - '0';
  }
  else if (tempChar >= 'A' && tempChar <= 'F') {
    return tempChar - 'A' + 10;
  }
  return 0;
}
@end

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

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

相关文章

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

    承接上文:iOS关于蓝牙框架BLE的开发--基础用法(上)上文提及到对特征码CBCharacteristic进行操...

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

    基础用法先说明一下,自己创建一个叫BluetoothManager的单例,在头文件BluetoothManager...

  • ios蓝牙参考

    参考文章:iOS中的蓝牙开发iOS-BLE蓝牙开发demo 官网 转载 CenteralManager学习笔记

  • iOS BLE蓝牙基础详解(两种模式)

    iOS BLE框架详解 概述 使用蓝牙开发无外乎两种,当做主设备(Central)或者外设(Peripheral)...

  • iOS蓝牙4.0基础开发

    1.蓝牙开发基础 蓝牙4.0是低电量模式所以也叫4.0BLE。本文将使用iOS系统提供的CoreBluetooth...

  • CoreBluetooth

    iOS-BLE蓝牙开发持续更新 - 简书 蓝牙打印小票 一个第三方 IOS BLE4.0蓝牙和外设连接和收发数据的...

  • 12月第三周

    iOS-BLE蓝牙开发持续更新 - IOS - 伯乐在线 ReactiveCocoa 中 RACSignal 所有...

  • iOS-蓝牙开发Mark

    iOS蓝牙的开发专题[http://liuyanwei.jumppo.com/2015/07/17/ios-BLE...

  • 蓝牙开发

    蓝牙 —— BLE (Bluetooth Low Energy),该教程以CoreBluetooth框架为基础开...

  • iOS 蓝牙BLE4.0开发

    蓝牙开发,现在普遍的都是BLE4.0低功耗蓝牙,CoreBluetooth是iOS 开发I比较推荐的一种开发方法...

网友评论

      本文标题:iOS关于蓝牙框架BLE的开发--基础用法(下)

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