繁体   English   中英

如何在 iOS Swift 中第二次连接到 BLE 设备

[英]How to connect to a BLE device the second time in iOS Swift

我正在开发一个连接到 BLE 设备的应用程序。 我可以成功连接,来回传递数据等。我遇到的问题是第二次运行应用程序时。 如果我第二次尝试连接到设备,在第一次配对后,似乎没有任何反应。 我按下了“连接”按钮,但什么也没得到。 为了让它再次连接,我必须进入设置,选择设备,然后忘记设备。 完成此操作后,一切正常。

我确信有一种简单的方法可以“重新连接”到设备,但我似乎找不到有关如何执行此操作的任何信息。 事实上,看起来我仍然在系统级别连接到设备,但我需要知道如何将其加载回本地 CBPeripheral 变量。

有人对我有什么建议吗?

这是我当前的连接代码:

private var centralManager : CBCentralManager!
private var peripheral: CBPeripheral!


centralManager = CBCentralManager(delegate: self, queue: nil, options: nil) //init central manager

func centralManagerDidUpdateState(_ central: CBCentralManager) {
        Print("Central state update")
        switch central.state {
        case .poweredOn:
            Print("Bluetooth is On, Starting scan.")
            peripheral_list.removeAll()
            centralManager.scanForPeripherals(withServices: nil,
                                              options: nil)
            case .unknown:
                Print("central.state is 'unknown'")
            case .resetting:
                Print("central.state is 'resetting'")
            case .unsupported:
                Print("central.state is 'unsupported'")
            case .unauthorized:
                Print("central.state is 'unauthorized'")
            case .poweredOff:
                Print("central.state is 'poweredOff'")
            @unknown default:
                Print("central.state **** Default *****")
        }
    }
    
    public func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        
        if let name = advertisementData["kCBAdvDataLocalName"] {
            if true /*name as! String == "RyanBT"*/ {
                Print("\nName   : \(name)")
                Print("UUID   : \(peripheral.identifier)")
                Print("RSSI   : \(RSSI)")
                for ad in advertisementData {
                    Print("AD Data: \(ad)")
                }
                
                peripheral_list.append(peripheral)
                picker.reloadAllComponents()
            }
        }
    }

    
    // The handler if we do connect succesfully
    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
        if peripheral == self.peripheral {
            Print("Connected!!!")
            peripheral.discoverServices(nil)
        }
    }
    
    func connectToDevice() {
        
        // Stop scan before connecting
        self.centralManager.stopScan()
        
        
        self.peripheral = self.peripheral_list[rowSelected]   //use selected peripheral
        self.peripheral.delegate = self
        
        // Connect!
        self.centralManager.connect(self.peripheral, options: nil)
    }

编辑:我添加了这个代码:

func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
        if error != nil {
            Print("\(error!)")
        }
    }

这是我第二次尝试连接时正在打印的消息:

Error Domain=CBATTErrorDomain Code=14 “Peer 删除的配对信息” UserInfo={NSLocalizedDescription=Peer 删除的配对信息}

即使您的应用程序未连接,iPhone 也可以连接到 BLE 设备。 实际的设备连接由操作系统处理,并在应用程序之间共享。 连接后,大多数设备不会做广告,因此您不会在didDiscover找到它们。 这完全是正常的,特别是如果您从未通过调用cancelPeripheralConnection断开连接。 但即便如此,它也可能发生。

假设您要连接到宣传特定服务的特定设备,您应该更改scanForPeripherals调用以传递这些服务而不是 nil。 scanForPeripherals除非您正在构建通用扫描仪,否则您不应将 nil 传递给scanForPeripherals 它速度较慢,并且可以退回您不想要的设备。

如果这样做,则可以通过调用retrieveConnectedPeripherals(withServices:)来检查已连接的设备。 鉴于您当前的代码,您可能会在centralManagerDidUpdateState执行此centralManagerDidUpdateState

或者,您可以通过外围 UUID(例如,将它们存储在 UserDefaults 中)跟踪您之前看到的各个设备。 您可以使用retrievePeripherals(withIdentifiers:)检查这些特定外围设备当前是否已连接。 同样,您可能会在centralManagerDidUpdateState执行此centralManagerDidUpdateState

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM