Future is not executed in Flutter side while called through FlutterMethodChannel from iOS

382 Views Asked by At

I'm calling a Flutter method from the native side, I have no problem with Android but iOS is not working. The Future is not executed and the result is never returned to iOS.

Here is a simple example.

Dart/Flutter side:

MethodChannel _methodChannel = const MethodChannel("theChannel");

void initChannel() {
  WidgetsFlutterBinding.ensureInitialized();

  _methodChannel.setMethodCallHandler((call) {
    switch (call.method) {
      case "flex":
        print("Flex channel");
        return Future.value('Flex');
      case "yep":
        print("Yep channel");
        return Future.delayed(const Duration(seconds: 1)).then((_) => 'Yep');
      default:
        throw MissingPluginException();
    }
  });
}

Swift/iOS side:

        let engine: FlutterEngine = FlutterEngine(name: "theEngine")
        let channel = FlutterMethodChannel(name: "theChannel", binaryMessenger: engine.binaryMessenger)

        channel.invokeMethod("yep", arguments: nil) { result in
            if(result is FlutterError) {
                print("Error")
            } else {
                print("Success")
            }
        }

Now the weird thing is the "flex" call works, with a Future completing directly.

In the "yep" case, I got the "Yep channel" and then the code hang there, not completing and not coming back to the iOS callback.

Everything works fine if I do the same with Android.

1

There are 1 best solutions below

0
Plumillon Forge On

So after a lot of debugging/testing, it's working.

Here is what I noticed and will guide you to do this:

  • You can fire different FlutterEngine but each of them will be executed in a different isolate.
  • So be careful of which one you're using when creating your channel.
  • You need to FlutterEngine.run() the engine before using it, and the next run won't do anything (if you need to run withEntrypoint afterward it directly returns without executing).

Now I got another problem with Flutter plugins not being initialized but it's another story.