首页 > 解决方案 > CoreBluetooth 有时无法检测到 CBPeripheral,除非访问控制中心/通知中心

问题描述

我正在开发一个连接到 BLE 外围设备的应用程序,有时我会遇到一个非常奇怪的问题,即 CentralManager 从未找到外围设备。但是,当在设备上拉下通知中心时,或者在向上滑动控制中心时,外围设备会立即显示并连接。

我试图找到这个问题的原因,但到目前为止我还没有找到任何东西。除了willResignActiveand didBecomeActive,似乎没有其他生命周期函数被调用(AFAIK),但在这两个函数中,除了打印它们已被调用之外,我没有做任何其他事情。

我已经确保使用self.centralManager.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])以防万一我搞砸了并且没有检测到初始扫描。

有谁知道这可能是什么原因,以及控制中心或通知中心对应用程序的影响如何解决这个问题?

谢谢!

编辑:一些额外的代码可能有助于找到问题。但是,我知道当问题发生时,discoveredPeripheral两者connectedPeripheral都是nil.

didConnect

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
    if centralManager.isScanning {
        centralManager.stopScan()
    }

    self.connectedPeripheral = peripheral
    self.discoveredPeripheral?.delegate = self

    debugPrint("\(Date()): Connected \(peripheral)")
    peripheral.discoverServices(nil)

    DispatchQueue.main.async {
        self.rssiTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.readPeripheralRSSI), userInfo: nil, repeats: true)
    }
}

didDiscover

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) {
        if peripheral.name == global.qnr && discoveredPeripheral == nil {
            centralManager.stopScan()
            debugPrint(
                "Discovered \(peripheral). " +
                "Initiating authentication sequence with \n" +
                "\tQNR: \(global.qnr)\n" +
                "\tSessionKey: \(global.sessionKey)\n" +
                "\tToken: \(global.bluetoothToken)")

            if self.discoveredPeripheral == nil || self.discoveredPeripheral != peripheral {
                self.discoveredPeripheral = peripheral
                self.centralManager.connect(peripheral, options: nil)
            }
        }
    }

startScanning

func scanForPeripherals() {
    if !centralManager.isScanning && global.sessionKey != "" {
        let services = [CONSTANTS.CBUUID]
        self.centralManager.scanForPeripherals(withServices: services, options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])
    }
}

标签: iosswiftcore-bluetoothcbperipheral

解决方案


当发现设备时,您必须通知委托人。我就是这样处理的。当我发现然后添加或重新添加时,我删除了以前添加的设备。将发现的设备添加到阵列后,如果您使用 tableView 显示,则重新加载表。

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
    if (peripheral.name != nil) {
        // remove previously added devices
        items.removeAll()
        items.append(peripheral)
    }
    // Set RSSI to custom peripheral signal property
    customPeripheral.signal = RSSI
    // Notify delegate for change in data.
    NotificationCenter.default.post(name: .reload, object: nil)
}

// Extension for reload tableView when peripheral array is updated
extension Notification.Name {
    static let reload = Notification.Name("reload")
}

在你的情况下。扫描完成并找到设备后,您会通知连接到您的设备的通知。

// Connect with peripheral
func connectPeripheral(peripheral: CBPeripheral) {
    centralManager.connect(peripheral, options: nil)
    centralManager.stopScan()
    print("Connecting")
}

推荐阅读