Study Record

[Flutter] WebView / HTTP 접속 권한 허용 본문

Flutter

[Flutter] WebView / HTTP 접속 권한 허용

초코초코초코 2023. 1. 27. 21:26
728x90

✍ pub.dev 사이트에서 WebView 오픈소스 살펴보기

 pub.dev 사이트는 Flutter 와 관련된 오픈소스 프로젝트들이 모여있는 공간이다.

 

pub.dev 사이트에서 webView를 검색하면 여러 가지 프로젝트들을 볼 수 있는데 그중 flutter.dev 는 flutter 공식 개발 팀을 의미한다.

 

 

✍ WebView_flutter 프로젝트에 적용하기

 

webview_flutter 프로젝트의 installing 탭에 적용하는 방법이 나와있는데 명령어 "flutter pub add webview_flutter" 를 먼저 실행한다.

 

그다음 pubspec.yaml 파일에 다음과 같이 webview_flutter: ^x.x.x 와 같이 추가되어 있는지 확인한 다음 [pub get] 버튼을 누른다. (webview_flutter: ^x.x.x 가 추가되지 않았다면 직접 dependencies 밑에 추가한다.)

pub get 버튼 참고 이미지

 

✍ WebView_flutter 간단한 사용법

 

먼저 WebViewController() 를 통해 controller 를 생성한다.

controller = WebViewController()
  ..setJavaScriptMode(JavaScriptMode.unrestricted)
  ..setBackgroundColor(const Color(0x00000000))
  ..setNavigationDelegate(
    NavigationDelegate(
      onProgress: (int progress) {
        // Update loading bar.
      },
      onPageStarted: (String url) {},
      onPageFinished: (String url) {},
      onWebResourceError: (WebResourceError error) {},
      onNavigationRequest: (NavigationRequest request) {
        if (request.url.startsWith('https://www.youtube.com/')) {
          return NavigationDecision.prevent;
        }
        return NavigationDecision.navigate;
      },
    ),
  )
  ..loadRequest(Uri.parse('https://flutter.dev'));

 

만든 controller 를 WebViewWidget() 인자로 넣어 사용한다.

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

 

WebViewController Class

 

< Method >

 

1. setBackgroundColor(Color color) → Future<void>

webView 의 배경화면을 설정한다.

setBackgroundColor(Colors.white);

 

 

 

2. setJavaScriptMode(JavaScriptMode javaScriptMode) → Future<void>

  • JavaScriptMode.disabled : 자바스크립트 실행 불가
  • JavaScriptMode.unrestricted : 자바스크립트 실행 가능

자바스크립트 실행 모드를 설정한다.

setJavaScriptMode(JavaScriptMode.unrestricted);

 

 

 

3. setNavigationDelegate(NavigationDelegate delegate)  Future<void>

navigation event 동안 발생하는 이벤트를 설정한다.

setNavigationDelegate(NavigationDelegate(
      onProgress: (int progress) {},
      onPageStarted: (String url) {},
      onPageFinished: (String url) {},
      onWebResourceError: (WebResourceError error) {},
      onNavigationRequest: (NavigationRequest request) {
        return NavigationDecision.navigate;
      }
))

 

+ NavigationDelegate Class

navigation request 를 하는 동안 승인되고 거절되는 이벤트를 위한 콜백 class 이다.

 

++ 이벤트 종류

 

++ onNavigationRequest

onNavigationRequest  NavigationRequestCallback? = FutureOr<NavigationDecision> Function(

        NavigationRequest navigationRequest

)

: navigation request 에 대한 결정이 보류될 경우 호출된다.

  • NavigationDecision.prevent : navigation 가 수행되지 않도록 한다.
  • NavigationDecision.navigate : navigation 가 수행되도록 한다.
// NavigationRequest({required String url, required bool isMainFrame})
NavigationDelegate(onNavigationRequest: (NavigationRequest request) {
    if (request.url.startsWith('https://www.youtube.com/')) {
        return NavigationDecision.prevent;
    }
    return NavigationDecision.navigate;
})

 

++ onWebResourceError 

onWebResourceError  WebResourceErrorCallback? = void Function(WebResourceError error)

리소스를 로딩하는데 실패했을 경우 호출된다.

NavigationDelegate(onWebResourceError: (WebResourceError error) {})

 

++ onProgress

onProgress  ProgressCallback? = void Function(int progress)

진행률 보고를 위해 페이지를 로드할 때 호출된다.

NavigationDelegate(onProgress: (int progress) {
    // Update loading bar.
})

 

++ onPageStarted

onPageStarted  PageEventCallback? = void Function(String url);

페이지 로드가 시작되면 호출된다.

NavigationDelegate(onPageStarted: (String url) {})

 

++ onPageFinished

onPageFinished  PageEventCallback? = void Function(String url);

페이지 로드가 끝나면 호출된다.

NavigationDelegate(onPageFinished: (String url) {})

 

 

4. canGoBack()  Future<bool>

이전 페이지에 대한 기록이 있으면 true 없으면 false 를 return 한다.

controller = WebViewController();
....
controller.canGoBack();

 

 

 

5. canGoForward()  Future<bool>

다음 페이지에 대한 기록이 있으면 true 없으면 false 를 return 한다.

controller = WebViewController();
....
controller.canGoForward();

 

 

 

6. clearLocalStorage()  Future<void>

webView 와 관련된 로컬 저장소의 기록이 지워진다. (캐시값들도 같이 지워진다.)

controller = WebViewController();
....
controller.clearLocalStorage();

 

 

 

7. enableZoom(bool enabled)  Future<void>

  • true : webView 의 줌 기능이 가능하다.
  • false : webView 의 줌 기능이 불가능하다.
controller = WebViewController();
....
controller.enableZoom(true);

 

 

8. goBack()  Future<void>

이전 페이지에 대한 기록이 있으면 그 페이지로 이동하고 없으면 아무런 동작을 하지 않는다.

controller = WebViewController();
....
controller.goBack();

 

 

 

9. goForward()  Future<void>

다음 페이지에 대한 기록이 있으면 그 페이지로 이동하고 없으면 아무런 동작을 하지 않는다.

controller = WebViewController();
....
controller.goForward();

 

 

 

10. loadRequest(...) → Future<void>

loadRequest(
    Uri uri,
    {
        LoadRequestMethod method = LoadRequestMethod.get,
        Map<String, String> headers = const <String, String>{},
        Uint8List? body
    }
) → Future<void>

webView 에 띄울 HTTP 요청한다.

loadRequest(Uri.parse('https://google.com'));

 

 

 

 

 

11. loadHtmlString(String html, {String? baseUrl})  Future<void>

html 문자열을 webView 에 띄워준다.

loadHtmlString("<b>강조 문자열</b>");

 

12. loadFlutterAsset(String key)  Future<void>

pubspec.yaml 파일에 있는 asset 들의 경로를 지정하면 그 asset 을 webView 에 띄워준다.

 

pubspec.yaml 파일에 asset/img/ 라고 경로를 지정한 상태이고 asset/img/free_hart_img.png 를 경로로 지정하고 싶다면 다음과 같이 함수를 요청한다.

loadFlutterAsset("asset/img/free_hart_img.png");

 

 

✍ HTTP 접속 허용 방법

 

Android

android/app/src/main/AndroidManifest.xml 에 useCleartextTraffic 을 true 로 설정해준다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.installed_test">
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:usesCleartextTraffic="true">
    </application>
</manifest>

use-permission 부분에 INTERNET 권한이 추가되어있지 않으면 추가한다.

 

 

IOS

ios/Runner/Info.plist 에 다음과 같은 내용을 추가한다.

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsLocalNetworking</key>
    <true/>
    <key>NSAllowsArbitraryLoadsInWebContent</key>
       <true/>
</dict>

728x90