React Native


1단계: react-navigation 라이브러리 설치

스크린 이동을 위해 react-navigation 패키지를 설치합니다.

npm install @react-navigation/native

해당 가이드는 Native Stack Navigator를 사용합니다.

npm install @react-navigation/native-stack

위 라이브러리와 의존성(dependencies)을 가지는 추가 라이브러리 설치가 필요합니다.

npm install react-native-screens react-native-safe-area-context

iOS의 경우 [Cocoapods] 를 통해 Pod 설치가 필요합니다.

npx pod-install ios

2단계: 런처 스크린 화면 구성

자사 서비스 내 인앱 게임을 구동하기 위해서는 WebView 를 포함하는 스크린의 생성이 필요합니다. 다음 가이드를 따라 진행 해주시기 바랍니다.

1. 런처 스크린 파일 생성

src/screens 경로에 런처용 스크린 화면을 추가합니다. 예시로 src/screens/launcher/Launcher.tsx 로 작성하였습니다.

2. Navigation 라우팅 추가

App.tsx 파일에서 Navigator 관련 정의를 추가합니다. Stack Navigator에 하위로 사용할 스크린에 해당하는 Stack을 생성합니다. Stack.Screenname 값이 라우팅 경로가 되고, component 는 스크린 컴포넌트를 넣어주세요.

예시 가이드에서는 launcher , banner 2가지 스크린을 사용하였습니다.

// App.tsx
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 라이브러리를 설치 합니다.

npm i react-native-webview

런처 스크린 내에 WebView 컴포넌트를 추가하고 source 속성에 런처 호출 URL을 요청합니다.

  • 자바스크립트 활성화를 위해 javaScriptEnabled 값을 true 로 설정합니다.

  • iOS는 메모리 문제로 Terminate 발생 가능성이 있어 reload 처리를 추가적으로 권장합니다.

    • WebView 관련 ref 선언을 추가합니다.

    • WebView 컴포넌트 내 onContentProcessDidTerminate 콜백을 통해 reload 처리합니다.

// src/screens/launcher/Launcher.tsx

import { WebView } from 'react-native-webview';
import { useRef } from 'react';

export default function Launcher() {
  const webviewRef = useRef<any>();

  ...
  return (
    ...
    <WebView
      ref={webviewRef}
      source={{
        uri: {런처 호출 URL},
        headers: {'Cache-Control': 'no-cache'},
      }}
      onMessage={onMessage}
      onContentProcessDidTerminate={() => {
        // webview reload
        webviewRef.current?.reload();
      }}
      javaScriptEnabled={true}
    />
    ...
  )
}

3단계: onMessage 설정 추가

런처와 React Native간의 통신을 수행하기 위해 WebViewonMessage 콜백을 정의합니다. WebView 에 로드된 런처에서 React Native로 메세지 이벤트를 전달합니다. 다음은 런처에서 전달하는 이벤트 케이스 입니다.

Type
Description

closeLauncher

런처의 Back 버튼 UI 클릭 시 (뒤로가기 처리)

launcherLoaded

런처 로드가 완료된 시점에 호출

timerMissionComplete

타이머 미션이 완료 되었을 때 호출

giftReceived

육성완료 시 호출

// src/screens/launcher/Launcher.tsx

import {WebView, WebViewMessageEvent} from 'react-native-webview';

export default function Launcher() {
  // WebView에서 보내온 메세지 처리
  const onMessage = (e: WebViewMessageEvent) => {
    const {type, inviteCode, infoMessage, link}
      = JSON.parse(e.nativeEvent.data);

    switch (type) {
      case 'closeLauncher':
        closeLauncher();
        break;
      case 'launcherLoaded':
        launcherLoaded();
        break;
      case 'timerMissionComplete':
        timerMissionComplete();
        break;
      case 'giftReceived':
        giftReceived();
        break;
    }
  };

  return (
    <View>
      <WebView
        ...
        onMessage={onMessage}
        ...
      />
    </View>
  );
}
// src/screens/launcher/Launcher.tsx

// 런처 종료 - 블리피 런처의 Back 버튼 UI 클릭 시 React Native에서는 뒤로가기 처리를 수행합니다.
const closeLauncher = () => {
  if (navigation.canGoBack()) {
    navigation.goBack();
  }
};

// 런처 로드 완료
const launcherLoaded = () => {
  // 런처의 로드가 완료된 후 추가적인 처리 필요 시 사용
};

// 타이머 미션 완료
const timerMissionComplete = () => {
  // 타이머 미션 완료 후 추가적인 처리 필요 시 사용
};

// 육성완료
const giftReceived = () => {
  // 육성완료 후 추가적인 처리 필요 시 사용
};

4단계: 런처 스크린 세로모드 고정

게임은 세로모드 해상도에 최적화 되어 스크린의 세로모드 고정이 필요합니다. 세로모드 고정을 위해 react-native-orientation-locker 라이브러리를 설치합니다.

npm install --save react-native-orientation-locker
  • 세로모드 고정 코드를 추가합니다.

// 추가
import Orientation from 'react-native-orientation-locker';

export default function Launcher() {
  ...
  
  // 추가
  useEffect(() => {
    // 화면 방향을 세로로 고정합니다.
    Orientation.lockToPortrait();

    return () => {
      // clean-up에서 다른 스크린에 영향 없도록 Orientations 해제
      Orientation.unlockAllOrientations();
    };
  }, []);

  return (
    <View>
      <WebView ... />
    </View>
  );
}
  • iOS 환경에서는 추가 설정이 필요합니다.

    • /ios/AppDelegate.m 파일을 열고 아래 코드를 추가합니다.

    • pod install 실행합니다.

// AppDelegate.m or AppDelegate.mm

// 추가
#import "Orientation.h"

@implementation AppDelegate
...

// 추가
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
  return [Orientation getOrientation];
}

...
@end

5단계: 화면 전환 설정

1. 딥링킹을 위한 설정 추가

React Native 환경 내 Android / iOS 두 플랫폼에서 딥링킹 처리를 위한 가이드입니다.

Android

  • 프로젝트 루트 경로 내 android/app/src/main/AndroidManifest.xml 파일 내 딥링킹 처리를 위한 intent-filter 를 추가합니다.

  • scheme 값은 프로모션 설정 시 입력할 딥링크에 사용하실 스키마 값으로 세팅해주세요.

// android/app/src/main/AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-permission android:name="android.permission.INTERNET" />

    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:allowBackup="false"
      android:theme="@style/AppTheme">
      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
        android:launchMode="singleTask"
        android:windowSoftInputMode="adjustResize"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <!-- 딥링크 이동을 위한 intent-filter 추가 -->
        <intent-filter>
          <action android:name="android.intent.action.VIEW" />
          <category android:name="android.intent.category.DEFAULT" />
          <category android:name="android.intent.category.BROWSABLE" />
          <data
            android:scheme="{사용할 scheme}" />
        </intent-filter>

      </activity>
    </application>
</manifest>

iOS

scheme 관련 정보는 직접 코드 추가 또는 Xcode 내 설정하는 2가지 방법이 있습니다.

  • 직접 코드 추가

    • info.plist 파일에 직접 코드를 추가합니다.

    • CFBundleURLTypes 관련 내용을 아래와 같이 추가합니다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    ...
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>CFBundleURLName</key>
            <string>{식별자(scheme와 동일하게 세팅해도 무관)}</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>{사용할 scheme}</string>
            </array>
	</dict>
    </array>
    ...
</dict>
</plist>
  • Xcode 내 설정

    • URL Types에 scheme 추가합니다.

프로젝트 /ios 경로 내에 몇가지 설정을 더 추가합니다.

// ios/프로젝트명/AppDelegate.mm

// 파일 상단에 추가
#import <React/RCTLinkingManager.h>

...

// @end위에 추가
- (BOOL)application:(UIApplication *)application
   openURL:(NSURL *)url
   options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
  return [RCTLinkingManager application:application openURL:url options:options];
}

...
@end

2. NavigationContainer linking 추가

React Native에서는 NavigationContainerlinking 기능을 사용하여 딥링크를 컨트롤합니다.

// App.tsx
export default function App() {
  // 사용할 scheme, host를 통해 이동할 screen을 지정
  const linking = {
    prefixes: ['{scheme}://'],
    screens: {
      {host}: 'screenName',
    },
  };

  return (
    // linking set
    <NavigationContainer linking={linking}>
      <Stack.Navigator screenOptions={{headerShown: false}}>
        ...
      </Stack.Navigator>
    </NavigationContainer>
  );
}

개발에 대한 추가 설명이 더 필요하신가요?

"[Client Admin] 로그인 → 오른쪽 하단 채널톡 위젯" 클릭 후 개발 카테고리에 문의 남겨주시면 기술 개발팀에서 확인 후 연락드리겠습니다.

Last updated