美文网首页iOS 蓝牙开发学习笔记
ios蓝牙开发学习笔记(二)central角色的实现

ios蓝牙开发学习笔记(二)central角色的实现

作者: idiot_lin | 来源:发表于2016-11-30 22:06 被阅读98次

    本文转载自:http://blog.csdn.net/swibyn/article/details/52096321

    Performing Common Central Role Tasks

    central角色的实现

    central 角色需要完成的几件事情,如搜索,连接,与peripheral交互数据。
    peripheral 角色同样需要完成几件事情,如,发布和广播服务,响应读,写,订阅请求

    本章中,你将学习如何完成central端的功能。
    1,创建central manager 对象
    2,发现和连接正在广播的peripheral
    3,浏览peripheral的数据
    4,发送读和写请求到peripheral设备
    5,订阅characteristic的值

    下一章你将学习如何开发peripheral角色的功能

    Starting Up a Central Manager

    创建Central manager对象

    myCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:nil];'

    在这里self设置成central角色的代理。dispath queue设置为nil,意味着central事件将交由main queue处理。

    创建central manager时,会触发centralManagerDidUpdateState: 代理方法。你必须实现这个代理。

    Discovering Peripheral Devices That Are Advertising

    搜索正在发送广播的peripheral

    [myCentralManager scanForPeripheralsWithServices:nil options:nil];

    注意:如果第一个参数设置成nil,那么centralmanager会返回所有被发现的peripherals,在实际应用中,你应该给他赋值 CBUUID 对象数组。这样只有有广播这些uuid服务的peripheral才会被返回,

    一旦发现peripheral,将触发
    centralManager:didDiscoverPeripheral:advertisementData:RSSi:
    代理方法,如果你想连接这个peripheral,请使用强引用变量引用它,这样系统就不会释放掉它。

    • (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral
      advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
      NSLog(@"Discovered %@", peripheral.name);
      self.discoveredPeripheral = peripheral;
      ...

    如果你想连接多个设备,你可以使用NSArray来管理他们。不管什么情况,一旦你找到所有你想要的设备,你应该停止扫描以便节省电量。

    [myCentralManager stopScan];

    Connecting to a Peripheral Device After You’ve Discovered It

    连接peripheral

    [myCentralManager connectPeripheral:peripheral options:nil];

    如果连接成功,则会触发centralManager:didConnectPeripheral:代理方法,与之通讯之前,你需要为它设置代理

    • (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
      NSLog(@"Peripheral connected");
      peripheral.delegate = self;
      ...

    Discovering the Services of a Peripheral That You’re Connected To

    查询peripheral的服务

    建立连接之后,就可以查询数据,第一步就是查询有哪些services。因为广播包有大小限制,在广播中可能没有显示全部的服务信息,这里你可以使用discoverServices: 来查询所有的services。

    [peripheral discoverServices:nil];

    注意:实际开发中,你不应该传值nil,因为这样做会返回所有的services,包括那些你不需要的services,这样做会浪费时间和电量。所以你应该传递你需要的uuids。

    查找到所有的服务会触发peripheral:didDiscoverServices:代理方法

    • (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
      for (CBService *service in peripheral.services) {
      NSLog(@"Discovered service %@", service);
      ...
      }
      ...

    Discovering the Characteristics of a Service

    查找characteristics

    发现service之后,下一步就是查找characteristics

    NSLog(@"Discovering characteristics for service %@", interestingService);
    [peripheral discoverCharacteristics:nil forService:interestingService];

    注意:实际开发中,不要传nil,这样做会返回所有的characteristics,包括那些你不感兴趣的characteristics。这样做即浪费时间又损耗电量。所以你应该传你需要的uuids的值

    查找到characteristics之后,会触发peripheral:didDiscoverCharacteristicsForService:error:代理方法

    • (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
      for (CBCharacteristic *characteristic in service.characteristics) {
      NSLog(@"Discovered characteristic %@", characteristic);
      ...
      }
      ...

    Retrieving the Value of a Characteristic

    获取数据

    一个characteristic只包含一种信息数据。比如恒温service下的温度characteristic只包含当前温度值,你可以通过读取或订阅来获得这个值。

    Reading the Value of a Characteristic

    读取characteristic的数据

    NSLog(@"Reading value for characteristic %@", interestingCharacteristic);
    [peripheral readValueForCharacteristic:interestingCharacteristic];

    获取到数据后peripheral调用peripheral:didUpdateValueForCharacteristic:error:代理方法

    • (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
      NSData *data = characteristic.value;
      // parse the data as needed
    ... 
    

    注意:并不是所有的characteristic都是可读的,你可以通过 characteristic的 proterties属性是否包含CBCharacteristicPropertyRead 常量来判断是否可读。在读一个不可读的characteristic的数据值,会在代理方法的error参数中体现异常信息

    Subscribing to a Characteristic’s Value

    订阅characteristic的值

    虽然通过readValueForCharacteristic: 可以有效获取静态值,但如果值是动态改变的,则最好使用订阅的方法。当值变化时,自动获得通知。
    设置订阅

    [peripheral setNotifyValue:YES forCharacteristic:interestingCharacteristic];

    订阅的时候peripheral会调用peripheral:didUpdateNotificationStateForCharacteristic:error: 代理方法。如果订阅失败了,也可以通过这个方法查询失败的原因

    • (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
      if (error) {
      NSLog(@"Error changing notification state: %@",[error localizedDescription]);
      }

    注意:并不是所有的characteristics都可以订阅,可以通过检查characteristic的properties属性是否包含CBCharacteristicPropertyNotify 或 CBCharacteristicPropertyIndicate常量来判断是否可订阅

    Writing the Value of a Characteristic

    写数据

    有时也是需要写数据的,比如恒温器,你需要设置目标温度。如果characteristic是可写的,那么你就可以调用writeValue:forCharacteristic:type: 方法来写入数据。如下:

    NSLog(@"Writing value for characteristic %@", interestingCharacteristic);
    [peripheral writeValue:dataToWrite forCharacteristic:interestingCharacteristic type:CBCharacteristicWriteWithResponse];

    当你写数据时,你可以标明写类型。上例中,写类型是CBCharacteristicWriteWithResponse, 这种情况下,不管有没有写成功,peripheral都会通过代理通知你。你需要实现这个方法以便处理异常情况。

    • (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
      if (error) {
      NSLog(@"Error writing characteristic value: %@",[error localizedDescription]);
      }
      ...

    如果你设置的写类型是CBCharacteristicWriteWithoutResponse, 那么写操作会以更有效的方式执行,但不保证写成功,并且不会有报告。peripheral不会通知任何回调。

    注意:characteristic可能只支持特定的写类型,或不支持写操作。你可以通过检查properties属性是否包含CBCharacteristicPropertyWriteWithoutResponse 或 CBCharacteristicPropertyWrite 来判断。

    相关文章

      网友评论

        本文标题: ios蓝牙开发学习笔记(二)central角色的实现

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