简体   繁体   中英

CoreBluetooth sometimes not detecting CBPeripheral unless accessing Control Center/Notification Center

I'm working on an app which connects to a BLE Peripheral, and I sometimes run into a very strange issue, where the Peripheral is never found by the CentralManager. However, when pulling down Notification Center on the device, or when swiping up Control Center, the Peripheral immediately shows up and connects.

I've tried to find the cause of this problem, but so far I haven't been able to find anything. Apart from willResignActive and didBecomeActive , no other lifecycle functions seem to be called (AFAIK), but in neither of those functions I do anything other than printing that they've been called.

I already made sure to use self.centralManager.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey: true]) in case I somehow screw up and not detect an initial scan.

Does anyone know what might be the cause of this, and how Control Center or Notification Center's influence on the app might solve this problem?

Thanks!

EDIT: Some extra code that might help find the issue. However, I know that when the problem happens, both discoveredPeripheral and connectedPeripheral are 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])
    }
}

You have to notify the delegate when a device(s) discovered. This is how I handle. I remove the previously added devices when I discover and then add or re-add. Once the discovered devices are added to the array, then reload the table if you are using the tableView to display.

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

In your case. You notify the notification to connect to your device once the scan is complete and the device is found.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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