Alex
Alex

Reputation: 591

Flutter/Swift await sink from synchronous context

I'm trying to make use of an async Swift Library for a Flutter application, however, I cannot await the async Swift. The code structure is the following:

...
    nfcChannel.setMethodCallHandler({
      (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
      switch call.method {
      case "doCGM":
        self.readCGM(result: result)
      default:
        result(FlutterMethodNotImplemented)
      }
    })
...

private func readCGM(result: @escaping FlutterResult) {
      let device = UIDevice.current
      
      var nfcManager = LibreTools.makeNFCManager(unlockCode: 0, password: Data([1, 2, 3, 4]))

      //perform a request
      let subscription = nfcManager.perform(.readHistory)
          .sink { reading in
             print("Reading done!!!")
             result(reading)
          }

      //sleep(5);
      //print("I am done")
  }

The flutter code is


  Future<bool> _handleIOS() async {
    // Sensor type
    logger.info('Trying to read data from iOS');
    dynamic data = await platform.invokeMethod('doCGM');
    logger.info('Random data: $data');
    return true;
  }

This code will not execute the subscription, currently, however, it will happen if the sleep is in the code. Is there a way to await the result without the sleep?

EDIT LOG

Upvotes: 0

Views: 673

Answers (1)

Richard Heap
Richard Heap

Reputation: 51751

You cannot wait for anything in a method call handler; you must return immediately. So, how do you return a result that took a while to become available?

You'll notice the escaping keyword in result: @escaping FlutterResult. This tells the compiler that the result closure may be called after the function has finished (as long as it is called on the main UI thread). The purpose of this is so you can call result from, for example, the anonymous function passed to sink.

Replace semaphore.signal() with result("test") and remove the remainder of the function - including the semaphore. (You will likely have to propagate the @escaping keyword to the definition of readCGM.)

Upvotes: 1

Related Questions