雙向溝通 App
此頁面將會介紹城市通開源專案中的 App 是如何與城市通做雙向溝通溝通。
連結機制
在 簡介 頁我們有提到,城市通透過 flutter_inappwebview 的 web-message-listeners 與 Web 溝通。
透過 flutter_inappwebview 所提供的方式,使用 WebMessageListener 物件於 WebView 註冊一個名為 flutterObject 的 object:
dart
// lib/util/web_message_handler/tp_web_message_listener.dart
WebMessageListener(
jsObjectName: 'flutterObject',
onPostMessage: (webMessage, sourceOrigin, isMainFrame, replyProxy) {
...
},
)jsObjectName定義了在 WebView 端該使用何名稱取得該物件。onPostMessage定義了收到網頁端訊息後的邏輯處理。
撰寫自定義的 MessageHandler
城市通專案已簡化了多數的訊息傳遞工作。
- 至
lib/util/web_message_handler/tp_web_message_handler.dart新增一個繼承自TPWebMessageHandler的 handler;實作:
dart
// lib/util/web_message_handler/tp_web_message_handler.dart
abstract class TPWebMessageHandler {
String get name;
Future<void> handle({
required Object? message,
required WebUri? sourceOrigin,
required bool isMainFrame,
required Function(WebMessage replyWebMessage)? onReply,
});
WebMessage replyWebMessage({required Object? data}) {
return TPWebStringMessageReply(
name: name,
data: data,
).message;
}
}name:定義 handler 名稱,與 雙向溝通網頁 - 專案內使用設計 中提及的 name 相對應。handle:定義收到資訊該作何處置,其中:message對應 雙向溝通網頁 - 專案內使用設計 結構內的data,也是 WebView 實際要傳給 App 端的資訊。onReply為回覆網頁端的方法,可使用replyWebMessage()來構建回覆的訊息。
⚠️ 注意
replyWebMessage()參數的data為需要能夠產出 JSON string 的類別或物件(number, boolean, string, null, list, map 或有實作 toJson() 之物件)。
- 至
lib/util/web_message_handler/tp_web_message_listener.dart的_cachedMessageHandlerslist 內新增你新建的 handler。messageHandler會回傳這個 list:
dart
// lib/util/web_message_handler/tp_web_message_listener.dart
static final List<TPWebMessageHandler> _cachedMessageHandlers = [
UserinfoWebMessageHandler(),
LaunchMapWebMessageHandler(),
PhoneCallMessageHandler(),
Agree1999MessageHandler(),
LocationMessageHandler(),
DeviceInfoMessageHandler(),
OpenLinkMessageHandler(),
NotifyMessageHandler(),
QRCodeScanMessageHandler(),
// add it here
];
static List<TPWebMessageHandler> get messageHandler => _cachedMessageHandlers;可參考以下檔案內已有的 Handler 以及其實作:
lib/util/web_message_handler/tp_web_message_handler.dart