简体   繁体   English

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

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

I am working on an app where I connect to a BLE device.我正在开发一个连接到 BLE 设备的应用程序。 I can successfully connect, pass data back and forth, etc. The problem I am having is when I run the app the second time.我可以成功连接,来回传递数据等。我遇到的问题是第二次运行应用程序时。 If I try to connect to the device a second time, after pairing to it the first time, nothing seems to happen.如果我第二次尝试连接到设备,在第一次配对后,似乎没有任何反应。 I press my 'connect' button and I get nothing.我按下了“连接”按钮,但什么也没得到。 To get it to connect again, I have to go into Settings, select the device, and forget the device.为了让它再次连接,我必须进入设置,选择设备,然后忘记设备。 Once I have done this, everything works fine.完成此操作后,一切正常。

I am sure there is a simple way to connect to "reconnect" to the device, but I can't seem to find any information on how to do this.我确信有一种简单的方法可以“重新连接”到设备,但我似乎找不到有关如何执行此操作的任何信息。 If fact, it looks like I am still connected to the device at the system level, but I need to know what to do to load it back into my local CBPeripheral variable.事实上,看起来我仍然在系统级别连接到设备,但我需要知道如何将其加载回本地 CBPeripheral 变量。

Does anyone have any suggestions for me?有人对我有什么建议吗?

This is my current connection code:这是我当前的连接代码:

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

Edit: I added this code:编辑:我添加了这个代码:

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

And this is the message it is printing when I try to connect the second time:这是我第二次尝试连接时正在打印的消息:

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

An iPhone can be connected to a BLE device even when your app is not connected.即使您的应用程序未连接,iPhone 也可以连接到 BLE 设备。 The actual device connection is handled by the OS, and shared among apps.实际的设备连接由操作系统处理,并在应用程序之间共享。 While connected, most devices will not advertise, so you won't find them in didDiscover .连接后,大多数设备不会做广告,因此您不会在didDiscover找到它们。 This is all completely normal, particularly if you never disconnect by calling cancelPeripheralConnection .这完全是正常的,特别是如果您从未通过调用cancelPeripheralConnection断开连接。 But even then it can happen.但即便如此,它也可能发生。

Assuming that you're connecting to specific devices that advertise specific services, you should change your scanForPeripherals call to pass those services rather than nil.假设您要连接到宣传特定服务的特定设备,您应该更改scanForPeripherals调用以传递这些服务而不是 nil。 As a rule you shouldn't pass nil to scanForPeripherals unless you're building a general-purpose scanner. scanForPeripherals除非您正在构建通用扫描仪,否则您不应将 nil 传递给scanForPeripherals It's slower, and can return devices you don't want.它速度较慢,并且可以退回您不想要的设备。

If you do that, you can then check for already connected devices by calling retrieveConnectedPeripherals(withServices:) .如果这样做,则可以通过调用retrieveConnectedPeripherals(withServices:)来检查已连接的设备。 Given your current code, you would likely do that inside centralManagerDidUpdateState .鉴于您当前的代码,您可能会在centralManagerDidUpdateState执行此centralManagerDidUpdateState

Alternately, you could keep track of individual devices that you've seen before by their peripheral UUIDs (by storing them in UserDefaults for example).或者,您可以通过外围 UUID(例如,将它们存储在 UserDefaults 中)跟踪您之前看到的各个设备。 You can check if those specific peripherals are currently connected using retrievePeripherals(withIdentifiers:) .您可以使用retrievePeripherals(withIdentifiers:)检查这些特定外围设备当前是否已连接。 Again, you'd probably do this in centralManagerDidUpdateState .同样,您可能会在centralManagerDidUpdateState执行此centralManagerDidUpdateState

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

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