转载

【iOS】CoreBluetooth3 作为 Central 时的数据读写(补充)

上一章谈到了当设备作为 Central 时,搜索、连接、读写的一些基本操作。几乎就是翻译了官方 API,除此之外,API 中还提到了一些枚举,以及在实际运用当中一些可以优化的点,这些都将在本文中一一介绍(就我目前遇到的需求而言)。

CBUUID

CBUUID  对象是用于 BLE 通信中 128 位的唯一标示符。Peripheral 的 Service,Characteristic,Characteristic descriptor 都包含这个属性。这个类包含了一系列生成 UUID 的方法。

UUID 有 16 位的,也有 128 位的。其中 SIG 组织提供了一部分 16 位的 UUID,这部分 UUID 主要用于公共设备,例如有个用蓝牙连接的心率监测仪,如果是用的公共的 UUID,那么无论谁做一个 app,都可以进行连接,因为它的 UUID 是 SIG 官方提供的,是公开的。如果公司是要做一个只能自己的 app 才能连接的设备,那么就需要硬件方面自定义 UUID。(关于这方面,包括通信的 GATT 协议、广播流程等详细介绍,可以看  GATT Profile 简介 这篇文章。讲得比较详细,能在很大程度上帮助我们理解 BLE 通信。)

CBUUID 类提供了可以将 16 位 UUID 转为 128 位 UUID 的方法。下面的代码是 SIG 提供的 16 位的心率 Service UUID 转为 128 位 UUID 的方法:

CBUUID *heartRateServiceUUID = [CBUUID UUIDWithString:@"180D"]; 

如果需要获取  NSString 形式的 UUID,可以访问  CBUUID 的  UUIDString  只读属性。

检查设备是否能作为 Central

初始化  CBCentralManager 的时候,传入的  self 代理会触发回调  centralManagerDidUpdateState: 。在该方法中可通过  central.state 来获得当前设备是否能作为 Central。 state 为  CBCentralManagerState  枚举类型,具体定义如下:

typedef NS_ENUM(NSInteger, CBCentralManagerState) {     CBCentralManagerStateUnknown = 0,     CBCentralManagerStateResetting,     CBCentralManagerStateUnsupported,     CBCentralManagerStateUnauthorized,     CBCentralManagerStatePoweredOff,     CBCentralManagerStatePoweredOn, }; 

只有当  state == CBCentralManagerStatePoweredOn  时,才代表正常。

检查 Characteristic 访问权限

如果不检查也没事,因为无权访问会在回调中返回 error,但这毕竟是马后炮。如果有需要在读写之前检测,可以通过 Characteristic 的  properties  属性来判断。该属性为  CBCharacteristicProperties 的  NS_OPIONS

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 }; 

多个权限可以通过  | 和  &  来判断是否支持,比如判断是否支持读写:

BOOL isSupport = characteristic.properties & (CBCharacteristicPropertyRead | CBCharacteristicPropertyWrite) 

写入后是否回调

在写入 Characteristic 时,可以选择是否在写入后进行回调。调用方法和枚举常量如下:

[self.connectedPeripheral writeValue:data forCharacteristic:connectedCharacteristic type:CBCharacteristicWriteWithResponse]; 
typedef NS_ENUM(NSInteger, CBCharacteristicWriteType) {     CBCharacteristicWriteWithResponse = 0,     CBCharacteristicWriteWithoutResponse, }; 

回调方法为:

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error; 

所以即使没有判断写入权限,也可以通过回调的 error 来判断,但这样比起写入前判断更耗资源。

原文  http://www.saitjr.com/ios/core-bluetooth-read-write-as-central-roal-supplement.html
正文到此结束
Loading...