iOS connectToDevice() after finding device ID fails with PlatformException

52 views Asked by At

Using flutter_reactive_ble I do the following

await _flutterReactiveBle
    .scanForDevices(withServices: services)
    .timeout(Duration(seconds: scanTimeoutDurationSeconds))
    .firstWhere((device) {
  _deviceId = device.id;
  debugPrint('device discovered: $device');

  return true;
}).onError((error, stackTrace) {
  debugPrint('error: $error');
  debugPrint('stackTrace: $stackTrace');
  _bleConnectionState.value = BleConnectionStatus.disconnected;
  throw BleBikeNotFoundException();
});

_connectionStateStream = _flutterReactiveBle
    .connectToDevice(
  id: _deviceId!,
)
    .listen((update) {
  _handleConnectionStreamUpdate(update);
},
  onError: (Object e) => {
        debugPrint('Connecting to device $_deviceId resulted in error $e'),
        dispose(),
        throw BleConnectionError(),
      });

The logs from this are as follows:

device discovered: DiscoveredDevice(id: E390E5E7-EC0B-37B9-3F26-27068C768EB7, name: imx8mmea-ucom, serviceData: {}, serviceUuids: [a25478a0-c922-11ee-9603-d3a9796f3cfa], manufacturerData: [], rssi: -56, connectable: Connectable.available)

Connecting to device E390E5E7-EC0B-37B9-3F26-27068C768EB7 resulted in error PlatformException(reactive_ble_mobile.Central.(unknown context at $105b88464).Failure:2, The operation couldn’t be completed. (reactive_ble_mobile.Central.(unknown context at $105b88464).Failure error 2.), {}, null)

This works well on android, but fails on iOS.

I'm running on latest iOS 17.3.1 on iPhone 13 mini I've added and enabled all permissions

Can anybody offer any advice? I have also posted on their official GitHub issues page.

1

There are 1 answers

0
rednaxela On

After much headache I found a similar issue where the package would throw the same error while using discoverServices() (now deprecated). https://github.com/PhilipsHue/flutter_reactive_ble/issues/724

For some reason I have to use a delay between connecting and subscribing like so:

await _flutterReactiveBle
    .scanForDevices(withServices: services)
    .timeout(Duration(seconds: scanTimeoutDurationSeconds))
    .firstWhere((device) {
  _deviceId = device.id;
  logDebug('device discovered: $device');

  return true;
}).onError((error, stackTrace) {
  logDebug('error: $error');
  logDebug('stackTrace: $stackTrace');
  _bleConnectionState.value = BleConnectionStatus.disconnected;
  throw BleBikeNotFoundException();
});

//DELAY HERE
await Future.delayed(const Duration(seconds: 3));

_connectionStateStream = _flutterReactiveBle
    .connectToDevice(
  id: _deviceId!,
)
    .listen((update) {
  _handleConnectionStreamUpdate(update);
},
        onError: (Object e) => {
              logDebug('Connecting to device $_deviceId resulted in error $e'),
              dispose(),
            });
//DELAY HERE
await Future.delayed(const Duration(seconds: 3));

final characteristic = QualifiedCharacteristic(characteristicId: bleCharacteristicGuid, serviceId: bikeNft.uuid, deviceId: _deviceId!);


_subscriptionStream = _flutterReactiveBle.subscribeToCharacteristic(characteristic).listen((data) {
  _handleSubscriptionStreamData(data);
}, onError: (Object error) {
  logDebug('Subscribing to device $_deviceId resulted in error $error');
  _bleConnectionState.value = BleConnectionStatus.disconnected;
  throw BleBikeNotFoundException();
});