티스토리 뷰
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 |