Core BlueTooth <二> Performing Common Central Role Tasks(实现一般的中心角色任务)

  实现在低功耗蓝牙通信中的核心作用的设备进行了一些常见的任务,例如,发现和连接到可用的外围设备,并探索,并与外围设备所提供的数据进行交互。与此相反,实现了外围角色还设备进行了一些常见的,但不同的任务,例如,出版和广告服务,并响应读,写,并从连接中切牙订阅请求。
 
   在本章中,您将学习如何使用蓝牙核心架构,由中央端执行的蓝牙低功耗任务,最常见的类型。后续将协助您开发的应用程序,基于代码的例子来实现您的本地设备上的核心作用。

  具体来说,您将学习如何:
 1. 启动中央管理器对象 .
 2. 发现并连接到那些正在广播的外围设备 .
 3. 你已经连接到外围设备后 , 浏览外围设备上的数据 .
 4. 对外设的服务的特性值 , 进行发送读取和写入请求 .
 5. 订阅的特性的值,当特性的值更新时得到通知 .

在下一章中 , 您将学习如何开发你的应用程序在本地设备上实现外围的作用。

    你觉得这一章中的代码示例是简单而抽象的 ; 您可能需要进行适当的修改,以将其纳入自己的真实世界的应用程序。与实施中的核心作用,包括提示,技巧更高级的主题,和最佳实践,覆盖在后面的章节中, Core Bluetooth Background Processing for iOS Apps and Best Practices for Interacting with a Remote Peripheral Device.( 核心蓝牙后台处理的 iOS 应用和最佳实践与远程外围设备交互 )


  第一步 启动中央管理器 Starting Up a Central Manager


  由于 CBCentralManager 对象是本地中心设备的蓝牙核心的面向对象的代表性,必须分配并初始化一个中央管理器实例,然后才能进行任何蓝牙低功耗处理。 你能够穷中央管理器通过调用 CBCentralManager    类的 initWithDelegate:queue:options:  方法.

如下所示:
myCentralManager =
       [[CBCentralManager alloc] initWithDelegate:self queue:nil options:nil];

在这个例子中 ,self 设置为收到核心作用事件的代理 . 指定调度队列为 nil, 中心管理分配中心作业事件 , 使用的是主队列 .

    当你创建一个中央管理器 , 中央管理器调用 centralManagerDidUpdateState: 方法的委托对象。您必须实现这个委托方法确保蓝牙支持低能量和中央设备上可以使用。关于如何实现这种委托方法的更多信息 , CBCentralManagerDelegate Protocol Reference .

第二步   发现正在广播的外围设备   Discovering Peripheral Devices That Are Advertising

  第一个中心任务是你想去实现发现可连接到 App 的外围设备.正如  Discovering Peripheral Devices That Are Advertising  所提到的,广播外围设备已知存在的主要方式.你通过调用  scanForPeripheralsWithServices:options:   方法,发现正在广播的外围设备.
[myCentralManager scanForPeripheralsWithServices:nil options:nil];
注意 : 如果你指定第一个参数为 nil,central manager 返回所有的发现的的外围设备 , 不管它们支持的服务 .
  在实际的应用程序,你可能会指定 CBUUID 对象,其中每一个代表一个外设的广告服务的通用唯一标识符( UUID )的数组。当你指定服务的 UUID 的数组,中央管理器只返回那些做广告的外设服务 , 只扫描你可能会感兴趣的设备。


第三步  连接 发现的外围设备   Connecting to a Peripheral Device After You’ve Discovered It

调用下面的方法连接到你的外围设备

 [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


确保你有一个外部设备连接后,你能开始探搜它的数据.在探搜的第一步是外围设备必须提供可发现可用的服务.
因为外部设备广播数据大小的限制,你能发现很多外围设备的广播的更多的服务应用.你能够发现所有的服务应用通过调用 CBPeripheral  类的 discoverServices:   方法.

 [peripheral discoverServices:nil];


注:在实际的应用程序,你会不会在零作为参数传递可能,因为这样做会返回一个外围设备上的所有可用的服务。由于外围可能包含更多的服务比你有兴趣,发现所有的人都可能会浪费电池寿命,并造成不必要的使用时间。更有可能的是,您将指定服务的 uuid ,你已经知道你有兴趣发现,如   Explore a Peripheral’s Data Wisely .(可以通过UUID指定搜索设备)


当指定的服务被发现后,外围设备(你连接的外围设备的对象)调用它的代理的  peripheral:didDiscoverServices:  方法, Core Bluetooth 创建 CBService   对象的一个数组, 每个服务 , 发现一个外围
  如以下所示 , 您可以实现这种委托方法访问发现的一系列服务

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



第四步 发现服务的特征   Discovering the Characteristics of a Service

假设您发现您感兴趣的服务 , 下一步b探索什么是外围提供发现所有的服务的特点。发现所有的特点 , 调用像服务一样简单 CBPeripheral   类的方法  discoverCharacteristics:forService:   指定合适的服务,如下:
 NSLog(@"Discovering characteristics for service %@", interestingService);
   [peripheral discoverCharacteristics:nil forService:interestingService];


注意:在真正的app中,第一参数设为nil,将返回外围设备的所有特征
因为周边的服务可能包含更多的比你感兴趣的特点 , 发现他们都可能浪费电池寿命和不必要的使用时间。更有可能的是 , 您将指定特征的 uuid, 发现你已经知道你感兴趣。




调用外围设备的代理方法指定的服务的特征  peripheral:didDiscoverCharacteristicsForService:error:  
Core Bluetooth 创建了一个 CBCharacteristic    对象的数组.
下面的实例显示怎么通过代理方法,去实现发现每一个特征.

- (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
特性包含一个值表示对周边的服务的更多信息。例如 , 健康温度计的测温特性服务可能的值显示在摄氏温度。您可以检索的价值特征通过阅读它直接或通过订阅。

1. 读取特征值 Reading the Value of a Characteristic

你能发现你感兴趣的服务的特征的值,你能够读取这个特征的值,通过调用 CBPeripheral  类的  readValueForCharacteristic:  方法.
如下:

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


  当你试图读取的特征的值时 , 外部设备调用它代理的 peripheral:didUpdateValueForCharacteristic:error: 方法去检索对象,
如果这个值成功的被检索,   你可以通过特征的价值属性访问它.像这样
:
- (void)peripheral:(CBPeripheral *)peripheral
didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic
            error:(NSError *)error {
 
   NSData *data = characteristic.value;
   // parse the data as needed
   ...



并不是所有的特点都保证有一个可读的价值。你可以确定一个特征值是可读的访问 CBCharacteristicPropertyRead 常数 ,详情在  CBCharacteristic Class Reference 。如果你想读的值是不可读的 , peripheral:didUpdateValueForCharacteristic:error: 委托方法返回一个相应的错误。

2. 订阅一个特征值 Subscribing to a Characteristic’s Value

通过使用 readValueForCharacteristic: 方法,读取特征的值, 对于一些有效的情况.   
它不是一个最有效的方法去检索特征的值的改变.对于大多数特征值的变化.
例如 , 心率在任何给定的时间应该检索通过订阅。当你订阅特征值的改变 ,从外部设备中 你收到一个通知当值改变的时候.


你能订阅特征的值,通过调用  CBPeripheral 类的   setNotifyValue:forCharacteristic: 方法,指定第一参数为YES,
如这样:
 [peripheral setNotifyValue:YES forCharacteristic:interestingCharacteristic];

但你企图订阅或不订阅特性值的时,外部设备调用它的对象的代理的 peripheral:didUpdateNotificationStateForCharacteristic:error: 方法.

因为一些原因,如果订阅请求失败,你能实现这个代理方法,您可以实现这种委托方法访问错误的原因

如下面的例子显示:
- (void)peripheral:(CBPeripheral *)peripheral
didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic
            error:(NSError *)error {
   if (error) {
       NSLog(@"Error changing notification state: %@",
          [error localizedDescription]);
   }
}


注意: 
  并不是所有的特征都配置,允许您订阅他们的值。你可以确定一个特点是 , 通过访问配置相关枚举常量 Characteristic Properties , 详细   CBCharacteristic Class Reference .
---------------
成功订阅特性特征值后 ,当这个值改变的时,外围设备会通知你的App 。每次值改变的时候,这个设备将调用它的代理方法 peripheral:didUpdateValueForCharacteristic:error:方法

去检索更新值,你能实现者个方法用相同的方式来描述上面的描述在 Reading the Value of a Characteristic .


3. 写入者个特征值   Writing the Value of a Characterib
stic

  对于一些用例 , 编写的价值是很有意义的特点。例如 , 如果您的应用程序与蓝牙低能量交互数字温控器 , 你可能想要为恒温器提供一个值 , 设置房间的温度。如果一个特性的值是可写 , 你可以写它的价值与一些数据 (NSData 的实例 ) 通过调用 writeValue:forCharacteristic: 类型 :CBPeripheral 类的方法 , 如下 :


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


    外围的写请求响应指定为 CBCharacteristicWriteWithResponse 通过调用周边 :didWriteValueForCharacteristic: 错误 : 委托对象的方法。如果写失败因为任何原因 , 你可以实现这个委托方法访问错误的原因 , 如以下示例所示 :


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


  注意 : 特征可能只允许执行某些类型的写在他们的价值。确定允许哪些类型的写一个特征的价值 , 您访问的相关属性特征属性枚举 ,CBCharacteristic 班上详细的参考。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值