PhilipsHue/flutter_reactive_ble

BLE unable to connect to the BLE device immediately after iOS app (in release mode) launches.

0100101101001011 opened this issue · 6 comments

Describe the bug
I have stored a BLE device UUID in the app local database and try to connect to it right after the flutter app launches. Everything works alright on Android (Both Debug and Release Mode) and iOS debug mode ( when manually start the app in the Xcode).

However, when I test the app in the iOS release mode, the BLE doesn't seem to be able to make the connection immediately after the app starts. I have to call it seconds later to make the connection.

There is this console output that might be relevant, but I'm not really sure:

[CoreBluetooth] API MISUSE: <CBCentralManager: 0x280665000> can only accept this command while in the powered on state

@0100101101001011 Are you doing WidgetsFlutterBinding.ensureInitialized() first thing in your main()?

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // ...
}

If not, does that fix the issue for you?

Actually, it seems you just have to wait till the powered-on status is actually reported by the API. Until then it's not allowed to perform BLE operations.

Thank you for your help! It solved the problem:) Why doesn't it occur on Android though?

I'm glad your issue is solved. I hope the same approach works for you on both iOS and Android and you need no platform checks?

The BLE stack implementations on iOS and Android are entirely different, even though they implement the same protocols. They may (and do) have some discrepancies and different limitations; this turns out to be one of them.

Let us keep the issue open and document the necessity to await for powered-on status before making BLE calls in README. It should be useful to many users of the library.

CC @remonh87

v11 commented

I had the same issue in iOS in release mode. It is not super well stated in the documentation.

Just in case somebody needs the code:

void waitBluetoothReady() async {
  statusStream = flutterReactiveBle.statusStream.listen((event) {
    switch (event) {
      // Connected
      case BleStatus.ready:
        {
          // Ready
          // Start scanning
          // ...
          break;
        }
      default:
    }
  });
}

I had the same issue in iOS in release mode. It is not super well stated in the documentation.

Just in case somebody needs the code:

You have just saved the day! Huge thanks