Reputation: 591
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
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