PhilipsHue / flutter_reactive_ble

Flutter library that handles BLE operations for multiple devices.
https://developers.meethue.com/
Other
660 stars 321 forks source link

iOS crashes when reconnecting #250

Open HelloBytes opened 3 years ago

HelloBytes commented 3 years ago

When playing with the bluetooth connection (enabling / disabling) couple of times on IOS this error occurs and the app crashes:

IOS 14 flutter_reactive_ble 2.7.3 Flutter 2.0

Assertion failed: file flutter_reactive_ble/ConnectTaskController.swift, line 16 Assertion failed: file flutter_reactive_ble/ConnectTaskController.swift, line 16

werediver commented 3 years ago

205 looks distantly related, though the failure is not the same.

werediver commented 3 years ago

Looking at the error message it seems that your app tries to connect to the same device while it's already being connected. The library may still have a flaw.

What exactly do you mean by "playing ... (enabling / disabling)"? Banging the toggle till the app crashes?

HelloBytes commented 3 years ago

When I disable or enable the bluetooth, or when I am out of range and there is a timeout, I try to reconnect to the device every xx seconds. It looks like when you try to connect multiple times this error occurs. Before I connect I check if there is a connection, like the example:

if (_connection != null) { await _connection.cancel(); }

marcel-bluestone commented 3 years ago

I have a similar crash experience, trying to subscribe to a notification stream after the connection has been established. (no toggling of bluetooth here!).

I am on iOS 14 Flutter 2.1 flutter_reactive_ble 2.7.3

Here's my crash report:

Assertion failed: file flutter_reactive_ble/PluginController.swift, line 103
Assertion failed: file flutter_reactive_ble/PluginController.swift, line 103
* thread #1, queue = 'com.apple.main-thread', stop reason = Assertion failed
    frame #0: 0x00000001ac4afff8 libswiftCore.dylib`_swift_runtime_on_report
libswiftCore.dylib`_swift_runtime_on_report:
->  0x1ac4afff8 <+0>: ret    
libswiftCore.dylib`_swift_reportToDebugger:
    0x1ac4afffc <+0>: b      0x1ac4afff8               ; _swift_runtime_on_report
libswiftCore.dylib`_swift_shouldReportFatalErrorsToDebugger:
    0x1ac4b0000 <+0>: adrp   x8, 344158
    0x1ac4b0004 <+4>: ldrb   w0, [x8, #0x998]
Target 0: (Runner) stopped.
HelloBytes commented 3 years ago

I have a similar crash experience, trying to subscribe to a notification stream after the connection has been established. (no toggling of bluetooth here!).

I am on iOS 14 Flutter 2.1 flutter_reactive_ble 2.7.3

Here's my crash report:

Assertion failed: file flutter_reactive_ble/PluginController.swift, line 103
Assertion failed: file flutter_reactive_ble/PluginController.swift, line 103
* thread #1, queue = 'com.apple.main-thread', stop reason = Assertion failed
    frame #0: 0x00000001ac4afff8 libswiftCore.dylib`_swift_runtime_on_report
libswiftCore.dylib`_swift_runtime_on_report:
->  0x1ac4afff8 <+0>: ret    
libswiftCore.dylib`_swift_reportToDebugger:
    0x1ac4afffc <+0>: b      0x1ac4afff8               ; _swift_runtime_on_report
libswiftCore.dylib`_swift_shouldReportFatalErrorsToDebugger:
    0x1ac4b0000 <+0>: adrp   x8, 344158
    0x1ac4b0004 <+4>: ldrb   w0, [x8, #0x998]
Target 0: (Runner) stopped.

Toggling does not cause this issue sorry for the misconception, I have changed the title. In my code I try to reconnect after it disconnects or fails or when bluetooth is ready (again).

marcel-bluestone commented 3 years ago

@HelloBytes thanks for the clarification. This seems to be a bug to me. My dart code does not seem to be the cause of the crash, as I don't have any problems with it on Android...

werediver commented 3 years ago

Toggling does not cause this issue sorry for the misconception, I have changed the title. In my code I try to reconnect after it disconnects or fails or when bluetooth is ready (again).

@HelloBytes Than you for clarification, it does make a difference.

@marcel-bluestone Even though your issue may be "structurally" similar, your stack-trace is different and the failing operation is different. I'd suggest you to open a separate ticket for it (or reference an existing one).

werediver commented 3 years ago

@HelloBytes Forgot to mention. As a workaround, you can try introducing a delay before you are trying to reconnect (300–500 ms). Please, let us know if that makes any difference.

HelloBytes commented 3 years ago

@HelloBytes Forgot to mention. As a workaround, you can try introducing a delay before you are trying to reconnect (300–500 ms). Please, let us know if that makes any difference.

I can try it tomorrow when I work on the project!

HelloBytes commented 3 years ago

It's look like it will only occur when you try to connect multiple times in a short time window. So now when connecting I set a flag that it is connecting. When a second attempt tries to connect and the flag is still connecting it will skip that attempt.

calebisstupid commented 3 years ago

I'm getting the same thing (along with https://github.com/PhilipsHue/flutter_reactive_ble/issues/269) when doing the following:

  1. enable ble pairing on device
  2. scan for devices in my code
  3. find and connect to device
  4. re-open app and re-enable ble pairing on device
  5. scan for device in my code
  6. find and (attempt to) connect to device (this fails due to timeout)
  7. after timeout, attempt to connect to device again and I get this crash
remonh87 commented 3 years ago

@calebisstupid I think it is best you add a small timeout between requests. Like mentioned above. BLE does not tend to appreciate subsequent request in a short period of time.

calebisstupid commented 3 years ago

@calebisstupid I think it is best you add a small timeout between requests. Like mentioned above. BLE does not tend to appreciate subsequent request in a short period of time.

In my testing, it doesn't matter if I wait seconds or an entire day. As long as my device is showing as a previous device in the iOS bluetooth settings, it will always timeout when attempting to reconnect.

bretmh commented 2 years ago

Before reconnecting close your existing stream to your previous connection.

AnimeshHestabit commented 2 years ago

IOS app is crashed after the connecting with device so for handle the crash using scanStream.cancel(), but after doing this one of my readCharacteristic is not working fine i am not getting the battery status from device, but this is working fine with Android. According to me this error is because of scanStream.cancel() because in IOS app we used this and Android we did not use this.

I am sharing the readCharacteristic method which is not working in IOS, please help me out into this.

version : flutter_reactive_ble: ^5.0.2

 if (Platform.isIOS) {
       connectedBluetooth.value = true;
            connectionForData();
            _scanStream.cancel();

   }
 Future<void> connectionForData() async {
    try {
 flutterReactiveBle
              .readCharacteristic(characteristicBattery)
              .then((List<int> result) {
            debugPrint("HERE ==>> connected bluetooth then");
            for (var i in result) {
              ///read the battery status (byte code)
              debugPrint("HERE ==>> connected bluetooth for");
              batteryStatus(i);
            }
          });
}, onError: (Object error) {

        CommonUtils.toastMesg(error.toString());
        // Handle a possible error
      });
    } catch (e) {
      debugPrint("HERE ==>> ${e.toString()}");
    }