美文网首页
二、中心设备实现CBCentralManager

二、中心设备实现CBCentralManager

作者: LucXion | 来源:发表于2023-05-07 22:35 被阅读0次

    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?) {
        }
    

    相关文章

      网友评论

          本文标题:二、中心设备实现CBCentralManager

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