欢迎访问个人博客 muhlenXi,该文章出自个人博客,欢迎转载,转载请注明来源: muhlenxi.com/2017/05/05/…。html
在这一节,主要是与 Remote Peripheral 交互的最佳实践,以及实际开发过程当中应该注意的事项。数组
CoreBluetooth 框架使 Central 端的工做变得容易透明、容易理解。也就是说,你的 APP 能够控制和负责 Central 的大部分方面,好比搜索设备、创建链接、与 Remote Peripheral 进行数据交互。本章将以负责的方式来提供一些规范和最佳实践,尤为是当你为 iOS 设备开发 APP 的时候。app
当开发一个 APP 与 BLE 设备交互时,须要铭记:BLE 通讯会经过你的设备向空中发射 Radio 信号。其余形式的无线通讯也可能须要使用设备的 Radio,好比,Wi-Fi,传统蓝牙以及使用 BLE 的其余 APP。所以要减小 Radio 的使用。框架
当开发 iOS 设备的 APP 时,最少次数使用 Radio 很重要,由于 Radio 的使用会对 iOS 设备电池的续航时间有不利影响。如下的这些规范将会帮助你更好的使用 Radio。做为回报,你的 APP 会良好运行和你设备电池的续航时间将会延长。ide
当你调用 CBCentralManager
类的 scanForPeripheralsWithServices:options:
方法来搜索正在广播数据的 Remote Peripheral 时,你设备的 Radio 会一直监听正在广播的设备,直到你中止搜索为止。性能
除非你须要搜索更多的设备,不然当你找到你想要链接的设备后就应该中止搜索,前几篇提到过,用 CBCentralManager
类的 stopScan
方法来中止搜索设备。ui
Remote Peripheral 设备可能会每秒发送多个广播数据包给监听的 Central,当你调用 scanForPeripheralsWithServices:options:
方法搜索设备时,该方法默认的行为是将一个 Peripheral 的多个发现事件合并成一个发现事件,也就是说,Central Manager 每找到一个新的 Peripheral 时才会调用 centralManager:didDiscoverPeripheral:advertisementData:RSSI:
代理方法,无论收到多少广播数据包都不会调用该方法。当已发现的 Peripheral 的广播数据发生变化时也会调用这一代理方法。spa
若是你想改变默认行为,调用 scanForPeripheralsWithServices:options:
方法时你能够指定 scan option 为 CBCentralManagerScanOptionAllowDuplicatesKey
,这样每当 Central 收到来自 Peripheral 的数据包就会建立一个发现事件。对于某些状况关闭默认行为会颇有用,好比基于 Peripheral 的 Proximity (靠近程度)来进行链接交互。Proximity 能够经过 Peripheral 的 接收信号强度指示(RSSI)的值来判断,也就是说,指定这个扫描选项会对电源的续航和 APP 的运行形成不利影响。所以,只在必要的状况下再指定该方法的 scan option。代理
当你开发 APP 的时候,对于特定的使用情景,一个 Peripheral 设备可能拥的大量的 Service 和 Characteristic 已经超过了你须要的数量 ,搜索 Peripheral 所有的 Service 和 Characteristic 对电源的续航和 APP 的性能带来不利影响。所以。你应该只搜索你的 APP 须要的 Service 和 Characteristic。code
举个例子,假如你链接的 Peripheral 有许多可用的 Service,可是你的 APP 只须要用到其中的两个。你只须要搜索这两个 Service 就能够了,只须要调用 CBPeripheral
类的 discoverServices:
方法时传入 Service UUID(用 CBUUID 对象表示) 数组就能够了。以下所示:
[peripheral discoverServices:@[firstServiceUUID, secondServiceUUID]];
复制代码
当你搜索到这两个须要的 Service 后,你能够用类似的方式来搜索你须要的 Characteristic,一样地,在调用 CBPeripheral
类的 discoverCharacteristics:forService:
方法时传入你想要的 Characteristic UUID(用 CBUUID 对象表示) 数组就能够了。
经过前面的文章,咱们了解到,获取一个 Characteristic 值的方式有两种:
readValueForCharacteristic:
方法来读取 Characteristic 的值。setNotifyValue:forCharacteristic:
方法来订阅 Characteristic 的值,这样当值发生改变后就会收到来自 Peripheral 的通知。对于值可能变化的 Characteristic 来讲,订阅是最佳实践方式,尤为是对于值频繁改变的 Characteristic,关于如何订阅一个 Characteristic 的值,能够查阅 Subscribing to a Characteristic’s Value.
当再也不须要链接的时候与设备断开链接能够帮助你减小 Radio 的使用,你应该在如下的情景中断开与 Peripheral 设备的链接:
isNotifying
属性来判断 Characteristic 的值是否通知。在上述的场景中,取消一些订阅并与 Peripheral 断开链接,你能够经过调用 setNotifyValue:forCharacteristic:
方法来取消订阅一个 Characteristic 的值,设置第一个参数为 NO
。你能够经过调用 CBCentralManager
类的 cancelPeripheralConnection:
方法来断开与 Peripheral 设备的链接。像这样:
[myCentralManager cancelPeripheralConnection:peripheral];
复制代码
提示:cancelPeripheralConnection:
方法是 nonblocking(非阻塞)的,一些 CBPeripheral
类的命令仍然等待 Peripheral,当你尝试断开链接可能没有完成执行.由于可能其余 APP 还在链接 Peripheral,取消一个本地链接不能保证设备物理链接马上断开。从 APP 的角度来看,认为 Peripheral 是断开的,Central Manager 会调用 centralManager:didDisconnectPeripheral:error:
代理方法进行回调。
使用 CoreBluetooth 框架,你有三种方式能够从新链接 Peripheral:
经过调用 retrievePeripheralsWithIdentifiers:
方法来恢复一个已知的 Peripheral 列表 --- Peripheral 是你发现的或者过去链接的。若是你要找的 Peripheral 在列表中,尝试去链接它。这种重连方式在 恢复已知的 Peripheral 列表
小节中有描述。
经过调用 retrieveConnectedPeripheralsWithServices:
方法来恢复系统当前已经链接的 Peripheral 列表,若是你要找的在列表中,则与它建立一个本地链接,这种重连方式在 恢复当前已链接的 Peripheral 列表
小节中有描述。
经过调用 scanForPeripheralsWithServices:options:
方法扫描和搜索 Peripheral,若是找到它,则链接。这种方式在 iOS BLE 开发小记[2]中有描述。
根据使用状况,每次重连 Peripheral ,你可能不想扫描和搜索一样的 Peripheral,你可能首先想用其余方式来重连。如图所示,一个可能的重连工做流程多是按照上面的提到的顺序依次尝试这些方式。
提示:你决定尝试的重连方式的个数取决于 APP 的使用状况,举个例子,你可能决定不使用第一种方式,或者你可能并行使用第一种和第二种方式。
当你第一次发现一个 Peripheral 时候,系统会建立一个标识符(用 NSUUID 对象表示的一个 UUID)来标识这个 Peripheral,你可使用 NSUserDefaults 来保存这个标识符。事后你能够尝试调用CBCentralManager
类的 retrievePeripheralsWithIdentifiers:
方法来恢复并从新链接这个 Peripheral,下面描述的一种方式就是使用这个方法来从新链接之前的 Peripheral。
当 APP 启动时,调用 retrievePeripheralsWithIdentifiers:
方法,传入一个包含 Peripheral 标识符的数组来发现和重连先前的 Peripheral,像这样:
knownPeripherals =
[myCentralManager retrievePeripheralsWithIdentifiers:savedIdentifiers];
复制代码
Central Manager 尝试在先前发现的 Peripheral中去匹配你提供的标识符,而后返回一个包含 CBPeripheral 对象的数组,若是没有匹配的对象,数组将会是空的。你应该去尝试其他的两种方式中的一种。若是数组不是空的,在界面中让用户去选择要重连哪个。
当用户选择 Peripheral 后,调用 CBCentralManager
类的 connectPeripheral:options:
方法去链接 Peripheral。若是 Peripheral 设备被链接后, Central Manager 会调用 centralManager:didConnectPeripheral:
代理方法,此时 Peripheral 重连成功。
提示:Peripheral 可能由于一些缘由不能链接,举个例子,设备不在 Central 附近,此外,一些 BLE 设备使用周期变化的随机设备地址。所以,即便设备在附近,从上次系统发现 Peripheral,设备的地址也可能发生改变,在这种状况下,你尝试链接的 CBPeripheral 对象与实际的 Peripheral 不相符。若是你不能从新链接 Peripheral,由于它的设备地址已经变了,你必须从新调用 scanForPeripheralsWithServices:options:
方法来搜索链接。
关于设备随机地址的详细信息,请查阅 Bluetooth 4.0 规范,第3卷,C部分,10.8 章节和 Bluetooth Accessory Design Guidelines for Apple Products.
另外一种重连 Peripheral 的方式就是检查你要链接的 Peripheral 是否一直被系统链接(举例,被另外一个 APP 链接),你能够调用 CBCentralManager
类的 retrieveConnectedPeripheralsWithServices:
方法,它返回一个 CBPeripheral 对象的数组,数组中包含当前系统已经链接的 Peripheral。
由于系统当前可能链接超过一个以上的 Peripheral,你能够传入一个 CBUUID 对象的数组来恢复你指定 Service的 Peripheral,若是当前链接的 Peripheral 中没有你指定的 Peripheral,数组将是空的,你应该尝试其他两种方式中的一种。若是数组不为空,在界面中让用户去选择要重连哪个。
假设用户选择了渴望的 Peripheral,经过调用 CBCentralManager
类的 connectPeripheral:options:
方法来本地化链接。即便系统一直链接着设备,你必须本地化链接后再进行交互。当创建了本地链接后,Central Manager 会调用 centralManager:didConnectPeripheral:
代理方法,此时设备重连成功。
一、Best Practices for Interacting with a Remote Peripheral Device
欢迎在本文下面留言一块儿交流心得...