React Navigation
(v6.x)
- native stack navigator 사용
typescript
npm install @react-navigation/native-stack
yarn add @react-navigation/native-stack
pnpm add @react-navigation/native-stack
1단계 : 블리피 런처스크린 화면 구성
React Native 프로젝트 내에 블리피 런처를 구동하기 위해서는 WebView를 포함하는 스크린이 필요합니다.
다음 가이드를 따라 진행해주시기 바랍니다.
1. 런처 스크린 화면 파일 생성
src
아래 screens
폴더 내에 런처 스크린 화면을 추가합니다.
가이드에서는 src/screens/launcher/Launcher.tsx
로 작성하였습니다.
2. Navigation 라우팅 추가
App.tsx
파일에서 Navigation 라우터에 블리피 런처스크린을 등록합니다. 화면을 추가합니다.
typescript
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from '@screens/home';
import LauncherScreen from '@screens/launcher';
const Stack = createNativeStackNavigator();
export type RootStackParam = {
launcher: undefined;
banner: { url: string };
};
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name="launcher" component={LauncherScreen} />
<Stack.Screen name="banner" component={BannerScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
3. WebView에 런처 URL 로드
리액트 네이티브에서 WebView
를 사용하기 위해서 react-native-webview
npm 라이브러리를 설치해야 합니다.
typescript
npm i react-native-webview
런처스크린 내에 WebView
컴포넌트를 추가하고 **{런처 URL}**을 요청합니다.- 자바스크립트 활성화를 위해
javaScriptEnabled
값을 true
설정합니다.
typescript
import { WebView } from 'react-native-webview';
export default function Launcher() {
return (
<WebView
source={{
uri: {런처 URL},
}}
onMessage={onMessage}
javaScriptEnabled={true}
/>
)
}
2단계 : onMessage 설정 추가
블리피 런처와 React Native간의 통신을 수행하기 위해 onMessage
함수를 사용합니다.
런처 스크린에서 onMessage
콜백 함수를 선언하고 WebView
로부터 메시지 데이터를 전달 받습니다.
WebView
에 구동된 블리피 런처로부터 전달받는 메시지는 아래 2가지 케이스 입니다.
Type | Description |
---|
closeLauncher | 블리피 런처의 Back 버튼 UI 클릭 시 (뒤로가기 처리) |
moveActivity | 광고 플로팅 배너 클릭 시 화면 이동
url 데이터가 넘어옴 (커스텀 스키마 형태) |
typescript
import { WebView, WebViewMessageEvent } from 'react-native-webview';
export default function Launcher() {
const onMessage = (e: WebViewMessageEvent) => {
const { type, url } = JSON.parse(e.nativeEvent.data);
switch (type) {
case 'closeLauncher':
closeLauncher();
break;
case 'moveActivity':
moveCustomSchema(url);
break;
}
};
return (
<View>
<WebView
source={{
uri: {런처 URL},
}}
onMessage={onMessage}
javaScriptEnabled={true}
/>
</View>
);
}
1. closeLauncher()
블리피 런처의 Back 버튼 UI 클릭 시 React Native에서는 뒤로가기 처리를 수행합니다.
typescript
const closeLauncher = () => {
if (navigation.canGoBack()) {
navigation.goBack();
}
};
전체 소스 코드
typescript
import { useNavigation } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { Alert, Platform, StatusBar, View } from 'react-native';
import { WebView, WebViewMessageEvent } from 'react-native-webview';
import { RootStackParam } from '../../../App';
import qs from 'qs';
interface CustomScheme {
url?: string;
}
export default function Launcher() {
const navigation = useNavigation<NativeStackNavigationProp<RootStackParam>>();
const closeLauncher = () => {
if (navigation.canGoBack()) {
navigation.goBack();
}
};
const moveCustomSchema = (url: string) => {
const pattern = /^bleepy://([a-z0-9-_.]*)/i;
if (!pattern.exec(url)) {
Alert.alert('올바른 스키마 패턴이 아닙니다.');
return false;
}
const type = pattern.exec(url)?.[1];
const data: CustomScheme = qs.parse(
url.substring(url.indexOf('?') + 1, url.length),
);
switch (type) {
case 'banner':
navigation.navigate('banner', {url: data.url ?? ''});
break;
}
};
const onMessage = (e: WebViewMessageEvent) => {
const { type, url } = JSON.parse(e.nativeEvent.data);
switch (type) {
case 'closeLauncher':
closeLauncher();
break;
case 'moveActivity':
moveCustomSchema(url);
break;
}
};
return (
<View
style={{
width: '100%',
height: '100%',
paddingTop: Platform.OS === 'ios' ? 50 : 0,
}}>
<StatusBar />
<WebView
source={{
uri: {런처 URL},
}}
onMessage={onMessage}
javaScriptEnabled={true}
/>
</View>
);
}