반응형

Flutter에서 WebView를 사용하는 방법을 정리하겠습니다.

WebView는 애플리케이션 내에서 웹 콘텐츠를 표시할 수 있게 해주는 위젯입니다. 이를 통해 Flutter 앱에서 웹 페이지를 렌더링할 수 있습니다.

 

1. WebView 패키지 추가

 

먼저 webview_flutter 패키지를 pubspec.yaml 파일에 추가합니다.

dependencies:
  webview_flutter: ^4.0.0  # 최신 버전 확인 필요

 

1.2 플랫폼별 설정

iOS (ios/Runner/Info.plist):

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

Android (android/app/build.gradle):

android {
    defaultConfig {
        minSdkVersion 19
    }
}

 

2. 기본 사용법

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class WebViewExample extends StatefulWidget {
  @override
  _WebViewExampleState createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  late WebViewController controller;

  @override
  void initState() {
    super.initState();
    controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..loadRequest(Uri.parse('https://flutter.dev'));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('WebView Example')),
      body: WebViewWidget(controller: controller),
    );
  }
}

3. 주요 기능

3.1 JavaScript 활성화/비활성화

controller.setJavaScriptMode(JavaScriptMode.unrestricted);

3.2 로딩 프로그레스 모니터링

NavigationDelegate(
  onProgress: (int progress) {
    print('WebView is loading (progress : $progress%)');
  },
)

3.3 페이지 로딩 이벤트

NavigationDelegate(
  onPageStarted: (String url) { print('Page started loading: $url'); },
  onPageFinished: (String url) { print('Page finished loading: $url'); },
)

3.4 에러 처리

NavigationDelegate(
  onWebResourceError: (WebResourceError error) {
    print('Error: ${error.description}');
  },
)

3.5 쿠키 관리

final cookieManager = WebViewCookieManager();
await cookieManager.setCookie(WebViewCookie(name: 'foo', value: 'bar', domain: 'example.com'));

4. 고급 기능

4.1 JavaScript과 Flutter 간 통신

controller.addJavaScriptChannel(
  'Toaster',
  onMessageReceived: (JavaScriptMessage message) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message.message)),
    );
  },
);

4.2 사용자 지정 사용자 에이전트

controller.setUserAgent('My Custom User Agent');


NavigationDelegate 예시

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class WebViewExample extends StatefulWidget {
  const WebViewExample({Key? key}) : super(key: key);

  @override
  State<WebViewExample> createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  late WebViewController controller;

  @override
  void initState() {
    super.initState();
    controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setNavigationDelegate(
        NavigationDelegate(
          onProgress: (int progress) {
            // 웹 페이지 로딩 진행률 업데이트
            print('WebView is loading (progress : $progress%)');
          },
          onPageStarted: (String url) {
            // 페이지 로딩 시작
            print('Page started loading: $url');
          },
          onPageFinished: (String url) {
            // 페이지 로딩 완료
            print('Page finished loading: $url');
          },
          onWebResourceError: (WebResourceError error) {
            // 웹 리소스 로딩 중 오류 발생
            print('Error: ${error.description}');
          },
          onNavigationRequest: (NavigationRequest request) {
            // 특정 도메인으로의 이동을 막고 싶을 때 사용
            if (request.url.startsWith('https://www.youtube.com/')) {
              print('Blocking navigation to ${request.url}');
              return NavigationDecision.prevent;
            }
            print('Allowing navigation to ${request.url}');
            return NavigationDecision.navigate;
          },
        ),
      )
      ..loadRequest(Uri.parse('https://flutter.dev'));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('WebView Example'),
      ),
      body: WebViewWidget(controller: controller),
    );
  }
}

 

NavigationDelegate는 WebViewController를 설정할 때 setNavigationDelegate 메서드를 통해 설정합니다. 일반적으로 WebViewController를 초기화하는 부분에 넣습니다. 주로 initState 메서드 내에서 이루어집니다.

다음은 NavigationDelegate를 올바르게 설정하는 방법을 보여주는 예제입니다:

 
WebView NavigationDelegate 예제
Click to open code

이 예제에서 주목해야 할 점들은 다음과 같습니다:

  1. NavigationDelegate는 WebViewController의 setNavigationDelegate 메서드를 통해 설정됩니다.
  2. initState 메서드 내에서 WebViewController를 초기화하고 설정합니다.
  3. NavigationDelegate는 여러 콜백 함수를 포함할 수 있습니다:
    • onProgress: 페이지 로딩 진행률을 추적합니다.
    • onPageStarted: 페이지 로딩이 시작될 때 호출됩니다.
    • onPageFinished: 페이지 로딩이 완료될 때 호출됩니다.
    • onWebResourceError: 웹 리소스 로딩 중 오류가 발생했을 때 호출됩니다.
    • onNavigationRequest: 새로운 URL로 이동하기 전에 호출됩니다. 여기서 특정 URL로의 이동을 차단할 수 있습니다.
  4. 각 콜백 함수 내에서 원하는 로직을 구현할 수 있습니다. 예를 들어, 로딩 진행률을 UI에 표시하거나, 특정 URL로의 이동을 차단하는 등의 작업을 수행할 수 있습니다.

이렇게 설정된 NavigationDelegate는 WebView의 다양한 이벤트를 처리하고 사용자 경험을 향상시키는 데 도움이 됩니다. 특정 요구사항에 따라 각 콜백 함수의 내용을 커스터마이즈할 수 있습니다.



5. 보안 고려사항

  • HTTPS 사용을 권장합니다.
  • 신뢰할 수 있는 웹사이트만 로드하세요.
  • 필요한 경우에만 JavaScript를 활성화하세요.

6. 성능 최적화

  • 웹뷰는 네이티브 위젯보다 성능이 떨어질 수 있으므로 필요한 경우에만 사용하세요.
  • 복잡한 웹 콘텐츠를 로드할 때는 로딩 인디케이터를 표시하세요.

7. 사용자 경험 개선

  • 뒤로 가기 기능 구현
  • 새로고침 버튼 추가
  • 로딩 진행률 표시

8. 플랫폼별 고려사항

  • iOS와 Android에서 웹뷰의 동작이 약간 다를 수 있으므로 두 플랫폼에서 모두 테스트하세요.
  • 플랫폼별 특정 기능이 필요한 경우 조건부 코드를 사용하세요.
반응형

'프론트엔드 > Flutter' 카테고리의 다른 글

flutter mvvm 패턴 정리 및 예제  (0) 2024.07.22
flutter form 제출 및 라우터 이동  (0) 2024.07.22
flutter local notifications - 알림  (0) 2024.07.22
flutter get_it 패턴  (1) 2024.07.22
flutter provider 패턴  (1) 2024.07.22

+ Recent posts