티스토리 뷰

flutter

Flutter Webview 연동하기

길 킴 2024. 9. 24. 09:57
728x90

Flutter Webview를 사용하려고 합니다. 

정상적인 웹앱 연동을 위해서는 크게 3가지의 기능이 필요합니다. 

1. 로그인 유지 

2. App -> Web 호출 

3. App <- Web 호출

앱에서 이미 로그인을 했는데, 웹뷰에서 또 로그인을 시키면 불편합니다. 따라서 보통은 앱에서 가지고 있는 인증토큰 (access_token)을 웹뷰의 header로 보내고 서버에서 사용자 로그인 처리를 해주는 방법으로 많이 합니다. 

(🤔 보통이라 함은.. 제가 많이 경험해본 것이니 꼭 보편적이라고는 단언할 수 없습니다.)

App과 Web의 통신도 상당이 중요합니다. 
앱에서 웹 페이지에 동적으로 특정 요청을 해야 하는 경우가 있을 수 있고, 웹에서 특정 동작 시점에 앱에게 정보를 전달해줘야 하는 경우가 있습니다. 
(예를들어, 설문조사 웹뷰 페이지를 진행하다가 모두 완료되었다는 사실을 알려주고 앱에서 특정 액션을 취해야하는 경우가 있습니다) 

먼저, flutter webview 는 webview_flutter 라이브러리를 이용합니다. 

# webview
webview_flutter: ^4.9.0

 

Solution

1. 로그인 유지

webview header 에 인증 토큰을 넣습니다. 

..loadRequest(myUrl,
    headers: <String, String>{'Authorization': '${secureStorage.read(key: SecureStorageKey.accessToken)}'});

위의 예시 코드는 Flutter SecureStorage에서 저장된 accessToken 값을 불러와서 webview header에 삽입하는 코드입니다. 

 

2. App -> Web 호출 

App: Flutter Webview controller를 이용하여 javascript 함수를 호출합니다. 

controller.value?.runJavaScript(
    "fromAppToWeb('키값', '토큰: ${await secureStorage.read(key: SecureStorageKey.accessToken)}');"); // 헤더 값을 JavaScript 함수로 전달
return null;

String 파라미터 2개를 가진 fromAppToWeb 함수를 정의하여서 첫번째 파라미터는 '키값' 으로, 두번째 파라미터는 '토큰: {accessToken}' 을 보냅니다. 

 

Web: App에서 정의한 함수명과 같은 것을 찾아서 함수 실행을 한다. 

<script>
    function fromAppToWeb(headerKey, headerValue) {
      // 전달받은 헤더 값 출력
      document.getElementById('header-value').innerText = headerKey + ' ,' + headerValue;
    }
</script>

정의된 DOM 객체의 id 가 'header-value' 인 녀석에게 'headerKey , headerValue' 텍스트를 입힌다.

 

3. App <- Web 호출

앞으로 설명할 채널명을 통한 호출방식은 Flutter의 WebView에서 JavaScript와 Flutter 간의 통신을 위해 특별히 구현된 방식입니다. 기본적인 JavaScript 문법은 아니며 오로지 Flutter 를 위한 문법입니다.


App: 채널명을 통해서 메시지 값을 전달 받는다. 

..addJavaScriptChannel(
  'everexWebviewHandler',
  onMessageReceived: (JavaScriptMessage message) {
    Map<String, dynamic> presedMap = jsonDecode(message.message);
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(presedMap['action'])),//TODO 여기부터 수정하기
    );
  },
)

everexWebviewHandler 라는 채널명을 통해서 json string을 전달받는 코드입니다. 

 

Web: 앱에서 정의된 채널명을 이용하여 postMessage() 함수를 호출한다. 

<script>
    function fromWebToApp(msg) {
        var json1 = `{
            "action": "exit",
            "data": "{\\"name\\": \\"boogil\\", \\"email\\": \\"aaa@naver.com\\" }"
        }`;
        var json2 = "{ 'action': 'exit', 'data': '{\"name\": \"boogil\", \"email\" : \"aaa@naver.com\" }'}"; // 동작 안함

        var json3 = '{ "action": "exit", "data": "{\\"name\\": \\"boogil\\", \\"email\\" : \\"aaa@naver.com\\" }"}';
        everexWebviewHandler.postMessage(json1);
    }
    
</script>

 

⚠️ 위의 예시에서 json2 의 경우는 시작이 큰 따옴표 (") 로 되어있습니다. 
나머지 json1, json3 의 경우는 시작이 작은 따옴표 (') 로 되어있습니다. 
json2 방식으로 json string을 보내면 flutter 에서 json 파싱이 되지 않음을 주의해주세요. 

'flutter' 카테고리의 다른 글

Flutter Mvvm Clean Architecture Guide  (0) 2024.09.13
flutter go_router vs auto_route  (0) 2024.09.11
flutter thread 분석  (0) 2024.06.05
Provider 라이브러리 사용  (0) 2020.02.23
How Flutter renders Widget  (0) 2019.11.23
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함