CoreBluetooth иногда не обнаруживает CBPeripheral, если не получает доступ к Центру управления / Центру уведомлений - PullRequest
0 голосов
/ 02 июня 2018

Я работаю над приложением, которое подключается к BLE Peripheral, и иногда я сталкиваюсь с очень странной проблемой, когда CentralManager никогда не обнаруживает Peripheral.Однако при отключении Центра уведомлений на устройстве или при работе с Центром управления периферийное устройство немедленно обнаруживается и подключается.

Я пытался найти причину этой проблемы, но пока не нашелне смог найти ничего.Кроме willResignActive и 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])
    }
}

1 Ответ

0 голосов
/ 02 июня 2018

Вы должны уведомить делегата при обнаружении устройства.Вот как я справляюсь.Я удаляю ранее добавленные устройства при обнаружении, а затем добавляю или повторно добавляю.Как только обнаруженные устройства будут добавлены в массив, перезагрузите таблицу, если вы используете для отображения 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")
}
...