BLE 的重要性相信已经无需多言了。现在可穿戴设备与手机之间的配对连接方式基本都是一色的 BLE。这篇教程会介绍 CoreBluetooth 从 iOS5 到 iOS7 的演变。另外,也会介绍怎么配置 CB central 跟 peripheral,来让他们之间进行通讯,还有一些最佳编程实践。

####简介
教程会分为两章。第一章,也就是本文,会包含 Core Bluetooth 的概念性内容,第二章提供一个实践案例。

#####背景
BLE 是基于 Bluetooth 4.0 规格的,定义了一系列协议,描述如何跟低功耗设备进行通讯。在 BLE 中有两个角色:

  • **Central(中心设备)**:它通常会定义通讯的逻辑。可以对外围设备进行扫描,连接,断开。另外,它会接受来自外围设备的信息。
  • **Peripheral(外围设备)**:一个有信息需要进行共享的设备(心率、温度等等)。这些信息会被推送或者广播出来。


下面这张图展示了一个 central 以及 peripheral


image


上面的两个角色在 iOS 中各有一个类型与之对应,分别为 CBCentralManagerCBPeripheral


CBCentralManager 管理那些被发现或者连接的 peripheral(CBPeripheral)。只要 CBCentralManager 跟一个 peripheral 连接了,它们之间就可以进行数据交互了。peripheral 中存储的数据,依据 service 跟 characteristic,被组织在一个树形结构中。


这些服务可以使消息提醒,血压,心率等等。官方的 GATT 服务定义列表可以在这里查找到。


service 中的 characteristic 实际上是 service 对应的某个实际的值。例如,在这个教程中,Blood pressure service 实际上就是在某个时刻中的血压值。下图描述了一个 peripheral,它拥有一个 service 跟两个 characteristic:


image


在 Core Bluetooth 中,peripheral 的服务用 CBService 对象来表示。同样地,peripheral server 中的 characteristic 在 CB 中使用 CBCharacteristic 对象来表示。下图描述了 CBService 中 peripheral 的层次结构:
image


一个给定的 peripheral 可以有多个 service,每个 service 可以有多个 characteristic。这两者都没有限定最大数量。


注意,你最好阅读一下官方文档Core Bluetooth Framework Reference,来通透地了解这部分内容。里面有更加详细的对象层次图以及说明。

#####Core Bluetooth 进化史
Core Bluetooth FrameWork 首次出现在 iOS5,引入了一种新的方式来在设备之间利用蓝牙进行无线通讯。在每一次 iOS 系统的版本升级中,苹果都对 CB 进行提升,并且引入新特性。


在 iOS5,CB 主要的特性是 CBCentralManagerCBPeripheral,Central,Client 跟 Observer。在这个版本中只有两个类存在,CBCentralManagerCBPeripheral。前者负责发现跟连接几个(有限数量)外设。后者负责具象化一个设备,并且创建一种机制允许 Central 访问外设中的可用数据。


在 iOS6,苹果提供了了几个 CB 特性,并且做了一些提升,包括 CBPeripheralManager,外设数据库捕获,广播,Peripheral 跟 Server。另外,CBPeripheralManager 提供了一种自定义的方式来创建 Server,还提供了一种机制定义了信息如何通过网络广播。还有,外设数据库抓取(peripheral database caching)极大地提升了蓝牙性能,特别是在扫描发现外设这个阶段。


在收集了几年的反馈之后,苹果在 iOS7 中提升了 CB FrameWork,主要在以下方面:

  • 更简单的设备管理
  • 更智能的外设
  • 性能提升
  • 应用的持久性
  • 内置服务
  • 状态的保存跟恢复
  • 数据库抓取进一步提升,并且支持 services,characteristics,还有 descriptors(之前只保存 service 跟 characteristic)
  • 对数据传输而言,数据传播的容量也改变了。它现在支持 MTU 交换请求,还有改变了每个 PDU 中数据的最大容量
  • iBeacon 技术允许用户查询定位,还有检测到特定设备或者用户的 iOS 设备的接近
  • 苹果通知中心服务(ANCS)是一种苹果定义的 GATT 服务,它暴露了一些 characteristic 来让附加设备可以接收到在 iOS 设备上的通知事件,例如通知到达,通知被修改,或者消失,同时还能获取那些事件的更多信息。通过这些服务,外设开发者可以对 iOS 设备的事件有极大的访问权限。然而,目前的 iOS 版本还只是支持读取通知数据而已(文中写在 iOS7 发布不久之时)


如果你需要开始 BLE 的开发,你需要将一下考虑铭记在心:

  • iOS 模拟器几乎不支持 CB,所以,开发的时候请用你的真实机器
  • 你需要支持 BLE 也就是蓝牙4.0的 iOS 设备。所有 iPhon4S 包括 4S 以后的设备都支持蓝牙4.0
  • 你的 APP 可以与 BLE 外设通信,这个外设可能是第二胎 iOS 设备或者一台 Mac

#####CB 后台处理
决定一个 APP 如何在后台跟前台工作非常重要。每个 APP 都应该在后台跟前台之前有差异化的表现,因为系统资源有限。默认情况下,大多数普通的 CB 任务(在 central 跟 peripheral 中)在 APP 进入后台的时候会被禁止掉,或者处于被挂起的状态。然而,你可以让你的 APP 支持 CB 后台执行模式,来让它从被挂起的状态中唤醒,处理一些特定事件。


要注意,就算你的 APP 支持 CB 后台执行模式,它也不能一直运行。在给定的时间点,系统可能需要终止你的 APP 来释放内存。尽管如此,CB 支持保存 central 跟 peripheral 的状态信息,好让 APP 在运行的时候恢复这些状态。


如果你的 APP 不支持后台执行,所有在 APP 挂起时发生的蓝牙事件都会被系统放入队里中暂存起来,并且在 APP 进入前台的时候被触发。下面有一些 alert,可以在建立了连接之后,调用 CBCentralManagerconnectPeripheral:options: 方法时定义。一共有三种:

  • CBConnectPeripheralOptionNotifyOnConnectionKey:如果 APP 在建立了成功的连接后被挂起,需要系统对某个外设显示一个 alert,可使用这个 key
  • CBConnectPeripheralOptionNotifyOnDisconnectionKey:在断开连接时 APP 被挂起,可使用这个 key 来让系统显示 alert
  • CBConnectPeripheralOptionNotifyOnNotificationKey:需要在 APP 被挂起的时候,为某个外设发送的所有通知显示 alert 时,可用这个 key


在另一方面,如果你的 APP 支持后台运行模式,你需要在工程中声明它。可以在 Info.plist 文件中使用 UIBackgroundModes 这个 key,或者在工程的 target 设置中 Capabilities 一栏里设置。当 APP 设置了之后,系统会将它从挂起的状态中唤醒,来处理蓝牙事件。这对需要跟固定时间间隔发送数据的外设通讯的 APP 来说很重要,例如心率监测仪。后台的角色也有两个,一个对应 central 另一个对应 peripheral。

#####CBCentralManager 的最佳实践
尽管 CB 让 central 的数据传输过程在 APP 中变得透明,但仍有一些事项,在开发蓝牙 APP 的时候需要纳入考虑。由于你在跟低功耗设备通讯,你需要记住,每个操作都会消耗你的蓝牙设备的能源。


因此,你需要考虑如下几个方面:

  • 设备扫描:确实需要扫描的时候,你应该只扫描新设备。将无线电的使用最小化,这很重要,因为无线电的使用对 iOS 设备的电池寿命有影响
  • 来自同个设备的多个广播:外围设备可能会1秒内发送多个广播包来宣告自己的存在,然后监听 central。因此,当你在调用 scanForPeripheralsWithServices:options: 方法的时候,可以使用 CBCentralManagerScanOptionAllowDuplicatesKey 这个 key 来让多个同样蓝牙包合并为一个来处理
  • 优化对外设的数据的访问:只在 APP 中访问外设中有必要被访问的 service 跟 characteristic
  • 订阅或者检测 characteris 的值:在 characteristic 改变时,你可以通过用户输入或者自动执行来取得 characteristic。对应地你需要各使用一个方法。
  • 终止不需要的连接:由于补货机制,你可以快速地重连。当 central 需要重连一个设备时,苹果提供一个指定的工作流程。如下图:


image

#####CBPeripheral 的最佳实践
CBCebtralManager 类似,CBPeripheral 有一些同样地实践条则,在创建一个高效率 APP 的时候需要遵从。


考虑到广播,要记住,当你的 APP 处于前台时,在最初的广播数据中,它最多能够使用28个字节来的空间。注意只广播那些确实重要的数据。同样,你需要给用户提供一种方法来根据需要广播,让用户因此得以控制广播的频次。


当你配置你的 characteristic 时,你应该让它们支持通知。因而需要将 CBAttributePermissionsReadable 这个属性添加到 CBMutableCharacteristic 对象的 permissions 中。


注意,由于蓝牙是一种新兴技术,越来越多的设备使用它来嗅探网络意图访问 free data。因此,你应该在访问外设的敏感数据时使用配对连接的方式。

####小结
读完这篇文章你应该直到 Core Bluetooth framework 的规格说明。在下一篇教程中,你会学习到如何用 CBCentralManagerCBPeripheral 来编程。


文章主要翻译自 iOS 7 SDK: Core Bluetooth - Theoretical Overview, Jorge Costa and Orlando Pereira,有个人修改。


以上