I am new to Flutter and I am writing an application that hosts a non-flutter website within InAppWebView
. I'm currently using web messages to post messages from my React website into Flutter
using the example mentioned here:
https://inappwebview.dev/docs/webview/javascript/communication#web-message-channels
The next step is to invoke a postMessage()
using the Flutter app's window stack like so: window.<CustomFlutterClient>.postMessage()
. This works perfectly fine. My message goes from the React
website to the Flutter widget hosting the InAppWebView
and then into the Flutter window stack.
But I want to try and do is to call Flutter's window.<CustomFlutterClient>.postMessage()
directly from my React website.
I was thinking of doing something along the lines of window.flutter_inappwebview.parent.<CustomFlutterClient>.postMessage()
. But that doesn't seem to work. Am I right to assume I have access to Flutter's window stack from within my React application while its inside the InAppWebView. Or should I stick to the system I have currently with two a two step hop?
Reposting the code from the link:
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) {
await InAppWebViewController.setWebContentsDebuggingEnabled(true);
}
runApp(new MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
InAppWebViewSettings settings = InAppWebViewSettings();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("Web Message Channels")),
body: SafeArea(
child: Column(children: <Widget>[
Expanded(
child: InAppWebView(
initialData: InAppWebViewInitialData(data: """
<!-- !!!!! COMPARABLE CODE IN MY REACT WEBSITE!!!!! -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebMessageChannel Test</title>
</head>
<body>
<!-- when you click this button, it will send a message to the Dart side -->
<button id="button" onclick="port.postMessage(input.value);" />Send</button>
<br />
<input id="input" type="text" value="JavaScript To Native" />
<script>
// variable that will represents the port used to communicate with the Dart side
var port;
// listen for messages
window.addEventListener('message', function(event) {
if (event.data == 'capturePort') {
// capture port2 coming from the Dart side
if (event.ports[0] != null) {
// the port is ready for communication,
// so you can use port.postMessage(message); wherever you want
port = event.ports[0];
// To listen to messages coming from the Dart side, set the onmessage event listener
port.onmessage = function (event) {
// event.data contains the message data coming from the Dart side
console.log(event.data);
};
}
}
}, false);
</script>
</body>
</html>
"""),
initialSettings: settings,
onConsoleMessage: (controller, consoleMessage) {
print(
"Message coming from the Dart side: ${consoleMessage.message}");
},
onLoadStop: (controller, url) async {
if (defaultTargetPlatform != TargetPlatform.android ||
await WebViewFeature.isFeatureSupported(
WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL)) {
// wait until the page is loaded, and then create the Web Message Channel
var webMessageChannel =
await controller.createWebMessageChannel();
var port1 = webMessageChannel!.port1;
var port2 = webMessageChannel.port2;
// set the web message callback for the port1
await port1.setWebMessageCallback((message) async {
print(
"Message coming from the JavaScript side: $message");
// when it receives a message from the JavaScript side, respond back with another message.
await port1.postMessage(
WebMessage(data: message! + " and back"));
});
// transfer port2 to the webpage to initialize the communication
await controller.postWebMessage(
message:
WebMessage(data: "capturePort", ports: [port2]),
targetOrigin: WebUri("*"));
}
},
),
),
]))),
);
}
}
TIA