런처 화면이 백그라운드 모드로 전환될 때 WebView의 pause , resume 상태 등을 체크하기 위해 필요합니다.
// pubspec.yaml
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
flutter_inappwebview: ^6.0.0
visibility_detector: ^0.4.0+2
1단계: 런처 위젯 추가
인앱 게임을 런처에 구동하기 위해서는 WebView를 사용하는 위젯을 생성해야 합니다. 다음 가이드를 따라 진행해주시기 바랍니다.
1. dart 파일 생성
기본적으로 lib 폴더 경로에 런처가 구동될 dart 파일을 생성합니다.
가이드에서는 screens 폴더를 생성 후 bleepy_screen.dart 파일을 생성하였습니다.
WebView 내에 런처를 실행하면 자바스크립트 로직이 핑 전송 API를 주기적으로 호출합니다. 따라서 위젯이 백그라운드 모드로 이동되면 inactive 상태로 처리되어야 정상입니다.
그러나 런처 위젯에서 다른 위젯으로 Navigator 를 통한 라우팅 시 플랫폼에 따라 예외적인 케이스가 존재합니다.
AOS의 경우 라우팅 시 inactive 상태로 변경되지 않는 이슈가 있어 직접 컨트롤이 필요합니다.
다음 가이드를 따라 코드를 추가해 주세요.
1. LiftCycle 감지 설정 추가
위젯의 LifeCycle 감지를 위해WidgetsBindingObserver 를 사용합니다.
initState 에서 addObserver 를 호출
dispose 에서 removeObserver 를 호출
해당 과정은 VisibilityDetector 라이브러리의 정상 동작을 위해 선행되어야 합니다.
// lib/screens/bleepy_screen.dart
class _BleepyLauncherScreenState extends State<BleepyLauncherScreen>
with WidgetsBindingObserver{
...
@override
void initState() {
super.initState();
// 최초 위젯 실행 시 호출
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
// 위젯이 메모리에서 제거될 때 호출
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
...
}
2. VisibilityDetector 라이브러리 추가
VisibilityDetector 라이브러리를 통해 현재 화면의 활성화 여부 판단이 필요합니다.
화면의 활성화/비활성화 여부에 따라 WebView에 아래와 같은 처리가 필요합니다.
화면 비활성화 시
WebView pause
화면 활성화 시
WebView resume
VisibilityDetector 라이브러리는 아래 옵션 표를 참고합니다.
Interface function
Type
Description
key
key
필수 입력 값
onVisibilityChanged
void Function(VisibilityInfo)
visibilityInfo 내 visibleFraction으로 활성화 여부 판단
double 형
1.0 - 활성화
0.0 - 비활성화
// lib/screens/bleepy_screen.dart
@override
Widget build(BuildContext context) {
...
// VisibilityDetector 추가
return VisibilityDetector(
key: const Key("banner-screen-visibility-detector"),
onVisibilityChanged: (visibilityInfo) {
// visibility change event
var visibleFlag = visibilityInfo.visibleFraction.toInt();
if(visibleFlag == 1){
// 화면 보여질 때 실행
webViewController?.resume();
} else {
// 화면 안 보여질 때 실행
webViewController?.pause();
}
},
child: SafeArea(...)
);
}
3단계: Javascript Handler 추가
런처와 Flutter간의 통신을 수행하기 위해 Javascript Handler 추가가 필요합니다.
자바스크립트 핸들러 작성 시 handlerName 값은 BlpLauncher 로 작성해야 합니다.
다음은 런처에서 전달하는 이벤트 케이스 입니다.
handlerName: BlpLauncher
Type
Description
closeLauncher
블리피 런처의 Back 버튼 UI 클릭 시 (뒤로가기 처리)
launcherLoaded
블리피 런처 로드가 완료된 시점에 호출
timerMissionComplete
타이머 미션이 완료 되었을 때 호출
giftReceived
육성완료 시 호출
// lib/screens/bleepy_screen.dart
InAppWebView(
key: webViewKey,
initialUrlRequest:
URLRequest(url: WebUri(widget.launcherUrl)),
initialSettings: options,
onWebViewCreated: (controller) {
webViewController = controller;
// 자바스크립트 핸들러 추가
controller.addJavaScriptHandler(handlerName: 'BlpLauncher', callback: (message) {
final data = jsonDecode(message[0]);
final key = data['type'];
switch (key) {
case "closeLauncher":
closeLauncher();
break;
case "launcherLoaded":
launcherLoaded();
break;
case "timerMissionComplete":
timerMissionComplete();
break;
case "giftReceived":
giftReceived();
break;
default:
break;
}
});
}
)
// lib/screens/bleepy_screen.dart
// 런처 종료
void closeLauncher() {
Navigator.of(context).pop();
}
// 런처 로드 완료
void closeLauncher() {
// 런처의 로드가 완료된 후 추가적인 처리 필요 시 사용
}
// 타이머 미션 완료
void closeLauncher() {
// 타이머 미션 완료 후 추가적인 처리 필요 시 사용
}
// 육성완료
void closeLauncher() {
// 육성완료 후 추가적인 처리 필요 시 사용
}
4단계: 런처 스크린 세로모드 고정 로직 추가
게임은 세로모드 해상도에 최적화 되어 스크린의 세로모드 고정이 필요합니다.
service.dart 패키지를 추가합니다.
SystemChrome.setPreferredOrientations 메서드를 통해 세로 방향으로 고정합니다.
// lib/screens/bleepy_screen.dart
// 화면 고정을 위해 상단에 다음 패키지를 추가
import 'package:flutter/services.dart';
@override
Widget build(BuildContext context) {
// ...
// 세로 위아래 방향 고정
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
return VisibilityDetector(
...
child: SafeArea(...)
);
}
5단계: 화면 전환 설정
1. shouldOverrideUrlLoading 사용
inAppWebView 에서 제공되는 shouldOverrideUrlLoading 를 사용하여 딥링크 정보를 받을 수 있습니다. URI 정보를 받아 Screen 분기 처리를 진행합니다.
URI 정보 - navigationAction.request.url
scheme - 딥링크 스키마
host - 딥링크 호스트
queryParameters - 딥링크 쿼리스트링
// WebView 선언 부분 코드 추가
InAppWebView(
...
shouldOverrideUrlLoading: (controller, navigationAction) async {
// uri 정보
var uri = navigationAction.request.url!;
// Deep Link scheme 값으로 조건문 추가
if (uri.scheme == {scheme}) {
// Deep Link host 값으로 조건문 추가
if (uri.host == {host}) {
// Query string 값을 전달하기 위해 arguments 추가
Navigator.pushNamed(context, '/{host}', arguments: uri.queryParameters);
return NavigationActionPolicy.CANCEL;
}
}
return NavigationActionPolicy.ALLOW;
},
...
)
개발에 대한 추가 설명이 더 필요하신가요?
"[Client Admin] 로그인 → 오른쪽 하단 채널톡 위젯" 클릭 후 개발 카테고리에 문의 남겨주시면 기술 개발팀에서 확인 후 연락드리겠습니다.