[Flutter] Webview, JSInterface 통신하기

gomguk.tistory.com/15 에서 작성한 앱에서 기능을 추가한다.

목적 : URI-3 에서 만든 앱에서 JavaScript Interface 등록한 함수를 html에서 호출하도록 변경한다.

패키지 변경

기존에 사용한 flutter 내장 Webview는 JS를 안정적으로 지원하지 않는다고 한다. 그래서 공식 패키지 중 "flutter_inappwebview" https://pub.dev/documentation/flutter_inappwebview/latest/index.html 를 이용한다.

  1. 설치

    • pubspec.yml 에서 flutter_inappwebview: 4.0.0
    • import 'package:flutter_inappwebview/flutter_inappwebview.dart';
    • Android X 가상화를 사용하므로 SDK 버전을 17 이상으로 설정한다.
      • /app/build.gradle 에서 minSdkVersion 17
    • 기존 웹뷰 위젯 사용 위치에서 InAppWebView로 변경해준다.
child: InAppWebView(
                  initialUrl: initurl,
                  initialHeaders: {},
                  onWebViewCreated: (InAppWebViewController controller) {
                    //webView = controller;
				}
),

 

서버 코드 작성

  • Flask, JS 사용
  •  
from flask import Flask, render_template
app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

if __name__=='__main__':
    app.run('0.0.0.0', port=8889, debug=True)

[app.py]

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Flutter InAppBrowser</title>

    </head>
    <body>
      <h3>Hi! I'm Test Page!</h3>
        <script>
           window.addEventListener("flutterInAppWebViewPlatformReady", function(event) {
             window.flutter_inappwebview.callHandler('Print', '*** Message From Server JS ***').then(function(result) {
               console.log(result);
             });
           });
        </script>
    </body>
</html>

[index.html]

앱에서 WebviewPlatformReady 이벤트를 수신하면 'Print'핸들러를 호출한다. 인자로는 문자열을 전달한다.

 

앱 코드 수정

return Scaffold(
            body: SafeArea(
                child: InAppWebView(
                  initialUrl: initurl,
                  initialHeaders: {},
                  onWebViewCreated: (InAppWebViewController controller) {
                    //webView = controller;

                    controller.addJavaScriptHandler(handlerName: "Print", callback: (args) {
                      print("From the JavaScript side:");
                      print(args);
                      return args;
                    });
                  },
                  onLoadStart: (InAppWebViewController controller, String url) {
                  },
                  onLoadStop: (InAppWebViewController controller, String url) {
                  },
                  onConsoleMessage: (InAppWebViewController controller, ConsoleMessage consoleMessage) {
                    log("Console: ${consoleMessage.message}");
                    showToast(consoleMessage.message);
                  },
                ),
            ),
          );

[poc.dart]

"Print" 이름을 가진 핸들러를 추가하고 이벤트가 발생하면 콘솔로 문장을 출력해서 실행을 확인한다.

앱에서도 확인할 수 있도록 메시지를 서버로부터 수신하면 showToast()를 통해서 토스트 메시지를 추가하였다.

콘솔과 앱에서 서버로 부터 수신한 메시지를 볼 수 있다.

사용한 URI Scheme - bob://deeplink.flutter.dev/?url=http://[server_domain]&token=a123

콘솔에서 확인한 JS 요청
Toast Message로 확인한 JS 요청

앱 배포하기(apk로 만들기)

  • flutter build apk
  • build/app/outputs/apk/release 경로에 app-release.apk로 존재
반응형