Central 的规范:查找、连接外设,订阅Characteristic,通过连接的Peripheral向Characteristic发送读写请求
一、保存中心设备管理对象 CBCentralManager
// 中心设备 CBCentralManager
lazy var centeralManager:CBCentralManager! = nil
// 连接的外设必须用属性强引用,否则会被系统忽略,收不到回调
lazy var peripheral:CBPeripheral! = nil
二、初始化中心设备
/*
初始化中心设备 options有两个key
1. CBCentralManagerOptionRestoreIdentifierKey (用于持久连接的): 中心设备UID,不能变,通过UID来恢复状态,可以通过命令行生成128位标准uid $uuidgen
2. [CBCentralManagerOptionShowPowerAlertKey:NSNumber(booleanLiteral: true)]
默认nil为主线程,设置了线程,所有的代理回调都会在同一个线程里回调,通过主线程连接不会造成阻塞
*/
centeralManager = CBCentralManager.init(delegate: self, queue: nil ,options: nil)
三、CBCentralManagerDelegate:
连接外设,保存外设,并通过外设扫描服务
// 1.中心设备初始化完成
func centralManagerDidUpdateState(_ central: CBCentralManager){
// 在central.state == .poweredOn的状态下,根据服务UUID来搜索外设
central.scanForPeripherals(withServices: [CBUUID.init(string: s1UUID),CBUUID.init(string: s2UUID)])
}
// 2.搜索到拥有 s2UUID服务 的外设广播
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber){
// 根据 peripheral.name 来进一步筛选外设,连接
// 关键的一步,根据名称+服务找到对应的外设后,将外设保存到本地再进行连接,否则会没有任何响应,在这里还可以加入信号强度的判断 RSSI
self.peripheral = peripheral
// 关闭扫描
central.stopScan()
// 尝试连接外设
central.connect(peripheral)
}
// 3. 接下来就是连接外设结果的相关代理方法
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
//连接外设成功
peripheral.delegate = self
//通过外设来扫描外设服务,接下来就会走外设代理 CBPeripheralDelegate,来与特征进行一系列交互
peripheral.discoverServices([CBUUID.init(string: s1UUID)])
}
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
// 连接外设失败
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
// 连接已经被断开
}
func centralManager(_ central: CBCentralManager, connectionEventDidOccur event: CBConnectionEvent, for peripheral: CBPeripheral){
// 状态发生改变
}
四、CBPeripheralDelegate
// 1.中心设备成功连接外设后,通过外设扫描服务的回调
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
// 在这个回调里,可以拿到外设的服务对象集合
for element in peripheral.services! {
// 通常你可以做两件事,1.发现子服务
peripheral.discoverIncludedServices([CBUUID.init(string: s2UUID)], for: element)
// 2.直接扫描服务中的特征
peripheral.discoverCharacteristics([CBUUID.init(string: s1c1UUID),CBUUID.init(string: s1c2UUID)],for:element)
}
}
// 1.2 扫描到子服务,接着扫描子服务特征
func peripheral(_ peripheral: CBPeripheral, didDiscoverIncludedServicesFor service: CBService, error: Error?) {
appendCenteralInfo(content: "didDiscoverIncludedServicesFor成功读取到服务\(service.includedServices)")
for element in service.includedServices! {
appendCenteralInfo(content: "我发现了子服务\(element.uuid)")
// 去查询子服务的特征
peripheral.discoverCharacteristics([CBUUID.init(string: s2c1UUID)], for: element)
}
}
// 2.扫描到特征,可以读、写、订阅特征
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
for characteristicItem in service.characteristics! {
if(characteristicItem.uuid.isEqual(CBUUID.init(string: s1c1UUID))){
// 只要是扫描服务特征,特征同一个回调,不区分主服务、子服务
// 这些请求,会生成CBATTRequest对象,并由外设捕获
peripheral.readValue(for: characteristicItem)
}else if(characteristicItem.uuid.isEqual(CBUUID.init(string: s1c2UUID))){
peripheral.setNotifyValue(true, for: characteristicItem)
}else if(characteristicItem.uuid.isEqual(CBUUID.init(string: s2c1UUID))){
peripheral.writeValue("我写信给你".data(using: .utf8)!, for: characteristicItem, type: .withResponse)
}
}
}
// 3.1 读取到特征值的回调
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
let data = characteristic.value
if let data = characteristic.value {
let str :String = String.init(data: data, encoding: .utf8) ?? ""
}
}
// 3.2 订阅到特征值的回调
func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
let data = characteristic.value
if let data = characteristic.value {
let str :String = String.init(data: data, encoding: .utf8) ?? ""
}
}
// 3.3 写入特征值成功的回调
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
}
网友评论