• Home
  • About
    • lahuman photo

      lahuman

      열심히 사는 아저씨

    • Learn More
    • Facebook
    • LinkedIn
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

Flutter에서 Webview 사용하기

29 Aug 2023

Reading time ~2 minutes

개인 프로젝트로 앱을 만들려고 합니다.

대부분 코드는 참고 자료를 따라서 개발했습니다.

import 'dart:io';

import "package:flutter/material.dart";
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_android/webview_flutter_android.dart';
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
import 'package:url_launcher/url_launcher.dart';

import 'menu.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'TODO APP',
      home: WebViewPage(),
    );
  }
}

class WebViewPage extends StatefulWidget {
  const WebViewPage({super.key});

  @override
  State<WebViewPage> createState() => _WebViewPageState();
}

class _WebViewPageState extends State<WebViewPage> {
  late final WebViewController _controller;
  static const platform = MethodChannel('fcm_default_channel');

  Future getAppUrl(String url) async {
    await platform.invokeMethod('getAppUrl', <String, Object>{'url': url}).then(
        (value) async {
      debugPrint('paring url : $value');

      if (value.toString().startsWith('ispmobile://')) {
        await platform.invokeMethod(
            'startAct', <String, Object>{'url': url}).then((value) {
          debugPrint('paring url : $value');
          return;
        });
      }

      if (await canLaunchUrl(Uri.parse(value))) {
        await launchUrl(
          Uri.parse(value),
        );

        return;
      } else {
        debugPrint('paring url : $value');
        return;
      }
    });
  }

  @override
  void initState() {
    super.initState();

    late final PlatformWebViewControllerCreationParams params;
    if (WebViewPlatform.instance is WebKitWebViewPlatform) {
      params = WebKitWebViewControllerCreationParams(
        allowsInlineMediaPlayback: true,
        mediaTypesRequiringUserAction: const <PlaybackMediaTypes>{},
      );
    } else {
      params = const PlatformWebViewControllerCreationParams();
    }

    final WebViewController controller =
        WebViewController.fromPlatformCreationParams(params);

    if (controller.platform is WebKitWebViewController) {
      (controller.platform as WebKitWebViewController)
          .setAllowsBackForwardNavigationGestures(true);
    }

    controller
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setBackgroundColor(const Color(0x00000000))
      ..setUserAgent("random")
      ..setNavigationDelegate(
        NavigationDelegate(
          onProgress: (int progress) {
            debugPrint('WebView is loading (progress : $progress%)');
          },
          onPageStarted: (String url) {
            debugPrint('Page started loading: $url');
          },
          onPageFinished: (String url) {
            debugPrint('Page finished loading: $url');
          },
          onWebResourceError: (WebResourceError error) {
            debugPrint('''
              Page resource error:
                code: ${error.errorCode}
                description: ${error.description}
                errorType: ${error.errorType}
                isForMainFrame: ${error.isForMainFrame}
          ''');
          },
          onNavigationRequest: (NavigationRequest request) async {
            // 2 채널이용
            if (!request.url.startsWith('http') &&
                !request.url.startsWith('https')) {
              if (Platform.isAndroid) {
                getAppUrl(request.url.toString());

                return NavigationDecision.prevent;
              } else if (Platform.isIOS) {
                if (await canLaunchUrl(Uri.parse(request.url))) {
                  await launchUrl(
                    Uri.parse(request.url),
                  );

                  return NavigationDecision.prevent;
                }
              }
            }
            debugPrint('allowing navigation to ${request.url}');

            return NavigationDecision.navigate;
          },
        ),
      )
      ..addJavaScriptChannel(
        'Toaster',
        onMessageReceived: (JavaScriptMessage message) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text(message.message)),
          );
        },
      )
      ..loadRequest(Uri.parse('https://d-q.duckdns.org/'));

    if (controller.platform is AndroidWebViewController) {
      AndroidWebViewController.enableDebugging(true);
      (controller.platform as AndroidWebViewController)
          .setMediaPlaybackRequiresUserGesture(false);
    }

    _controller = controller;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Hello World'),
      ),
      body: WillPopScope(
        onWillPop: () async {
          if (await _controller.canGoBack()) {
            _controller.goBack();
            return false; // Prevent the app from exiting
          }
          return true; // Allow the app to exit
        },
        child: WebViewWidget(controller: _controller),
      ),
    );
  }
}

위의 코드는 다음과 같은 문제가 있습니다.

  • firebase auth popup 로그인 안되는 현상

참고자료

  • [Flutter] 웹뷰(WebView)


flutterwebview Share Tweet +1