central.retrieveConnectedPeripherals (withServices: [SERVICE_UUID]) возвращает ноль - PullRequest
0 голосов
/ 29 апреля 2020

У меня есть логика повторного подключения BLE c, которая сначала извлекает подключенное устройство, используя указанный c сервисный UUID, если не найден, а затем извлекает предыдущее подключенное устройство с сохраненным периферийным UUID. Если периферийный UUID не найден, центральный менеджер будет сканировать и обнаруживать с тем же UUID службы. Однако сканирование работает, и центральный менеджер может обнаружить периферийное устройство. Но если инициировать переподключение из приложения, и в этом случае BLE все еще подключен на уровне ОС (отображается как подключенный в настройках iOS BT), central.retrieveConnectedPeripherals (withServices: [SERVICE_UUID]) ничего не возвращает.

Есть ли что-то, чего мне не хватает для создания central.retrieveConnectedPeripherals (withServices: [SERVICE_UUID]) возвращает подключенные периферийные устройства с SERVICE_UUID?

Вот соответствующий код:

    // master function to control the connection logic
    private func connect(with peripheralIdentifier: String) {
        // connectedPeripheral is always nil even when BLE is connected on OS level
        if let connectedPeripheral = retrieveConnectedPeripheral(forIdentifier: peripheralIdentifier) {
            logger.d("peripheral is already connected in OS, establishing local connection...")
            self.peripheral = peripheral
            central.connect(connectedPeripheral, options: nil)
            return
        }

        if let peripheral = retrievePeripheral(forIdentifier: peripheralIdentifier) {
            logger.d("peripheral was previous connected, attempting to reconnect...")
            self.peripheral = peripheral
            central.connect(peripheral, options: nil)
            return
        }

        // start scan only when peripheral was never connected
        startPairing()
    }

    private func retrieveConnectedPeripheral(forIdentifier uuid: String) -> CBPeripheral? {
        return central
            .retrieveConnectedPeripherals(withServices: [SERVICE_UUID])
            .first
    }

    private func retrievePeripheral(forIdentifier uuid: String) -> CBPeripheral? {
        let p = central.retrievePeripherals(withIdentifiers: [uuid]).first
        logger.d("retrieved peripheral has services \(p?.services)") // it's always [], even when peripheral.discoverServices is called in didConnect callback
        return p
    }
    private func startPairing() {
        central.scanForPeripherals(
            withServices: [
                SERVICE_UUID
            ],
            options: nil)
    }

    func centralManager(_ central: CBCentralManager,
                        didDiscover peripheral: CBPeripheral,
                        advertisementData: [String: Any],
                        rssi RSSI: NSNumber) {

        if foundPeripheral(peripheral.name) {
            logger.d("""
                discovered a matching peripheral with \(String(describing: peripheral.name)),
                UUID \(peripheral.identifier),
                advertisementData \(advertisementData.description)
                """)
            self.peripheral = peripheral
            self.central.connect(peripheral, options: nil)
        }
    }

    func centralManager(_ central: CBCentralManager,
                        didConnect peripheral: CBPeripheral) {
        let uuid = peripheral.identifier
        // stores the UUID for reconnection 
        setPeripheralUuid(forKey: identifier, uuid: uuid)
        peripheral.delegate = self
        // calling this because the Developer Doc says without this, peripheral.services will be []. But after calling this, it's still []
        peripheral.discoverServices([SERVICE_UUID])
        stopScan()
    }

    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        if error == nil {
            logger.d("discovered services: \(peripheral.services)") // falls into this case, but it's []
        } else {
            logger.e("Failed to discover service for \(peripheral)!", error)
        }
    }

Как упомянуто в комментарии к коду, не уверен, что central.retrieveConnectedPeripherals (withServices: [SERVICE_UUID]) ничего не возвращает, связанный с периферийным устройством. ничего не возвращает. Вполне возможно, что есть что-то очевидное, что мне не хватает t

...