Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scanForDevices should not use 'assert(!central.isScanning)' #838

Open
nissaba opened this issue Jan 30, 2024 · 5 comments
Open

scanForDevices should not use 'assert(!central.isScanning)' #838

nissaba opened this issue Jan 30, 2024 · 5 comments

Comments

@nissaba
Copy link

nissaba commented Jan 30, 2024

In the function

func scanForDevices(name: String, args: ScanForDevicesRequest, completion: @escaping PlatformMethodCompletionHandler) {
        guard let central = central
        else {
            completion(.failure(PluginError.notInitialized.asFlutterError))
            return
        }

        assert(!central.isScanning)

        scan = StreamingTask(parameters: .init(services: args.serviceUuids.map({ uuid in CBUUID(data: uuid.data) })))

        completion(.success(nil))
    }

you should not use the assert(!central.isScanning) as this will crash an app that is trying connect to a device and wants to move to scaning to all device, the libray does not offer a way (not that I have seen) to stop/interupt this process.

This is the case for my app. When starting the app I will call connectToAdvertisingDevice to find the last connected device or to reconnect to the curent used device. If the user at some point wants to scan for an other device, the code needs to have a way to kill the process of this scanForDevices, as there si no way to interupt it asking to discover new devices will lead to a crash.

What should the code do? it should stop/kill the current decovery process and initiate the new request call.

func scanForDevices(name: String, args: ScanForDevicesRequest, completion: @escaping PlatformMethodCompletionHandler) {
        guard let central = central
        else {
            completion(.failure(PluginError.notInitialized.asFlutterError))
            return
        }

        if central.isScanning {
            central.stopScan()
            //other cleanup code
        }

        scan = StreamingTask(parameters: .init(services: args.serviceUuids.map({ uuid in CBUUID(data: uuid.data) })))

        completion(.success(nil))
    }
@nissaba
Copy link
Author

nissaba commented Feb 14, 2024

ping!

@Taym95
Copy link
Collaborator

Taym95 commented Mar 1, 2024

Hi thanks for report, PR are welcome

@Albert-Jan
Copy link

Albert-Jan commented Jul 1, 2024

Facing the same issue, any tips/recommendations would be appreciated

@i13Proietti
Copy link

I'm in trouble too with this problem. Waiting for the solution

@YueLiXing
Copy link

YueLiXing commented Aug 16, 2024

I have found the right way

class ShareReactiveBle {
  static Uuid gattUUID = Uuid.parse('****');
  static Uuid meshUUID = Uuid.parse('****');
  static final ShareReactiveBle _instance = ShareReactiveBle._internal();

  factory ShareReactiveBle() => _instance;

  late final FlutterReactiveBle _ble;
  StreamSubscription<DiscoveredDevice>? _subscription;
  final StreamController<DiscoveredDevice> _stateStreamController = StreamController();

  late Stream<DiscoveredDevice> stream;

  FlutterReactiveBle get ble => _ble;

  ShareReactiveBle._internal() {
    _ble = FlutterReactiveBle();
    _ble.statusStream.listen((event) {
      Log.d('statusStream $event');
    });
    stream = _stateStreamController.stream.asBroadcastStream();
  }

  void scan() {
    _subscription?.cancel();
    final filterService = Platform.isIOS ? [gattUUID, meshUUID] : <Uuid>[];

    _subscription = _ble.scanForDevices(withServices: filterService, scanMode: ScanMode.lowLatency).listen((event) {
      _stateStreamController.add(event);
    }, onError: (exception) {
      _stateStreamController.addError(exception);
      stopScan();
    });
  }

  void stopScan() {
    _subscription?.cancel();
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants