美文网首页
iOS CBPeripheralManager 手机作为外设 广

iOS CBPeripheralManager 手机作为外设 广

作者: 漫步的老狼 | 来源:发表于2024-06-20 17:44 被阅读0次
    class BlePeripheralManager:NSObject{
        var peripheralManager: CBPeripheralManager?
        var UUID_SERVER: CBUUID = CBUUID.init(string: "1234")
    
        //读写的特征值
        var UUID_CHAR_READ: CBUUID = CBUUID(string:"5678")
    
    
        
        
        var characteristic_w:CBMutableCharacteristic?
        var dataQueue: [Data] = []
        var isSending = false
        var isConnect = false
        
        override init() {
            super.init()
    
            peripheralManager = CBPeripheralManager(delegate: self, queue: nil)
    
        }
    
        
        func stopAdvertising(){
            peripheralManager?.stopAdvertising()
    
        }
        
        func setupServices() {
            // 创建一个服务和特征
            let serviceUUID = UUID_SERVER
            let service = CBMutableService(type: serviceUUID, primary: true)
            
            let characteristicUUID = UUID_CHAR_READ
            let characteristic = CBMutableCharacteristic(
                type: characteristicUUID,
                properties: [.read,.write,.notify,.writeWithoutResponse],
                value: nil,
                permissions: [.readable,.writeable]
            )
    
            self.characteristic_w = characteristic
            // 将特征添加到服务中
            service.characteristics = [characteristic]
            
            // 将服务添加到Peripheral Manager
            peripheralManager?.add(service)
        }
        func startAdvertising() {
    
            let advertisementData: [String: Any] = [
                CBAdvertisementDataLocalNameKey: "iOSBle",
                CBAdvertisementDataServiceUUIDsKey: [UUID_SERVER]
            ]
            if peripheralManager?.state == .poweredOn {
                peripheralManager?.startAdvertising(advertisementData)
            }else{
                
                
            }
    
        }
        func sendData(data: Data) {
               dataQueue.append(data)
               processQueue()
           }
        func processQueue() {
            guard let transferCharacteristic = characteristic else {
                return
            }
             guard self.peripheralManager?.state == .poweredOn else { return }
             guard !isSending else { return }
             
             isSending = true
    
             DispatchQueue.global().async {
                 while !self.dataQueue.isEmpty {
                     let data = self.dataQueue.removeFirst()
           
                     if let peripheralManager = self.peripheralManager{
                         transferCharacteristic.value = data
                         let success = peripheralManager.updateValue(data, for: transferCharacteristic, onSubscribedCentrals: nil)
                         
                         if !success {
                             // 发送失败,将数据重新插回队列的第一个位置
                             self.dataQueue.insert(data, at: 0)
                             break
                         }
                         
                         // 为了避免过频繁发送,加入适当的延时
                         Thread.sleep(forTimeInterval: 0.1)
                     }
                 }
                 self.isSending = false
             }
         }
        func bleConnect(_ isConnect:Bool){
            self.isConnect = isConnect
    
        }
        
        
    }
    //MARK: ==== CBPeripheralManagerDelegate ====
    extension BlePeripheralManager: CBPeripheralManagerDelegate{
        //蓝牙状态变化
        func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
            if peripheral.state == .poweredOn {
                if let p = self.peripheralManager,!p.isAdvertising{
                    if !isConnect{
         
                    }
                }
            }
            print("peripheral.state = \(peripheral.state)")
        }
    
        
        func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) {
            if error == nil{
                self.startAdvertising()
            }
        }
        //发送数据的时候
        func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
              print(#function)
            self.processQueue()
        }
        // 中心端停止订阅
        func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didUnsubscribeFrom characteristic: CBCharacteristic) {
              print(#function)
            self.bleConnect(false)
            self.startAdvertising()
        }
        // 中心端开始订阅
        func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didSubscribeTo characteristic: CBCharacteristic) {
              print(#function)
            self.bleConnect(true)
            self.stopAdvertising()
        }
        
        
        func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest) {
              print("didReceiveRead")
            if request.characteristic.uuid == UUID_CHAR_READ {
                // 为读取请求提供数据
    //            request.value = "Hello, World!".data(using: .utf8)
    //            peripheralManager?.respond(to: request, withResult: .success)
    //            
            }
        }
    
        func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) {
              print("didReceiveWrite")
            for request in requests {
                if request.characteristic.uuid == UUID_CHAR_READ {
                    if let value = request.value {
                        // 处理写请求的数据
    //                    let string = String(data: value, encoding: .utf8)
    //                    
    //                    peripheralManager?.respond(to: request, withResult: .success)
                    }
                }
            }
        }
        
        
    }
    
    

    注意事项及开发中的现象:
    1、两个苹果手机一个作为外设,一个作为中心设备的时候, 连接成功后断开想二次连接的时候,外设手机得蓝牙重启,才能下一次连接。安卓设备为中心设备的时候没有这个现象。
    2、发送数据的时候 要切成19字节 以内
    3、CBAdvertisementDataManufacturerDataKey 无法带参数
    4、中心端要订阅特征
    5、发送数据的时候经常会失败 出现这个问题解决了请在评论里回复一下,目前为止 以上代码测试是没有问题的。

    相关文章

      网友评论

          本文标题:iOS CBPeripheralManager 手机作为外设 广

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