@tenqube/visual-reward-react-native
v1.1.6
Published
Tenqube Visual Reward SDK for React Native
Readme
React Native
React Native WebView 기반 리워드 광고 SDK입니다.
요구사항
- React Native 0.76+
- iOS 13.0+
- Android minSdk 24
설치
npm (권장)
https://www.npmjs.com/package/@tenqube/visual-reward-react-native
npm install @tenqube/visual-reward-react-native react-native-webview
수동 설치
Visual Reward React Native SDK
- https://github.com/tenqube/visual-reward-sdk-react-native/releases
visual-reward-react-native-{version}.zip을 다운로드한 뒤 압축을 해제합니다 (zip에는android/,ios/네이티브 모듈이 포함되어 있습니다).package.json에file:경로 및react-native-webview를 추가합니다."dependencies": { "@tenqube/visual-reward-react-native": "file:./visual-reward-react-native", "react-native-webview": ">=13.0.0" }npm install
iOS pod install
두 방법 모두 iOS는 추가로
pod install을 실행합니다.cd ios && pod install
VisualRewardContainer 루트 추가
- 앱의 루트 컴포넌트(예:
App.tsx)에<VisualRewardContainer />을 추가합니다.
import { VisualRewardContainer } from '@tenqube/visual-reward-react-native';
export default function App() {
return (
<>
<YourNavigator />
<VisualRewardContainer />
</>
);
}권한
iOS
IDFA 조회(
getIDFA)를 사용하려면Info.plist에 ATT 사용 목적 문자열을 추가해야 합니다.<key>NSUserTrackingUsageDescription</key> <string>맞춤형 광고 제공을 위해 기기 식별자를 사용합니다.</string>ATT 권한 요청은 SDK가 웹뷰 로드 전 네이티브
ATTrackingManager로 자동 처리합니다. 이미 권한이 결정된 경우 팝업 없이 즉시 진행됩니다.
Ad Manager WebView 광고 연동
- SDK 의존성·App ID·초기화는 모두 호스트 앱에서 설정이 필요합니다.
- 호스트 앱에 Google Mobile Ads SDK가 링크돼 있으면, SDK가 리워드 웹뷰를 자동으로
registerWebView에 등록해 WebView 내부 광고(AdSense/GPT/IMA HTML5)의 수익화·측정 신호를 개선합니다. - 기존에 애드몹 등을 사용 중인 경우 정상 적용 여부만 확인해주시면 됩니다.
의존성
# GMA WebView API for Ads
npm install react-native-google-mobile-adsApp ID
AndroidManifest.xml
<!-- App ID 누락 시 시작 크래시 --> <meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy" /> <!-- WebView 전용일 때만 추가. 자체 광고도 서빙하면 이 메타데이터는 삭제 --> <meta-data android:name="com.google.android.gms.ads.INTEGRATION_MANAGER" android:value="webview" />Info.plist
<!-- App ID 누락 시 시작 크래시 --> <key>GADApplicationIdentifier</key> <string>ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy</string> <!-- WebView 전용일 때만 추가. 자체 광고도 서빙하면 이 키는 삭제 --> <key>GADIntegrationManager</key> <string>webview</string>
초기화
호스트 앱 시작 시 1회 초기화합니다.
import mobileAds from 'react-native-google-mobile-ads'; useEffect(() => { mobileAds().initialize(); }, []);
시퀀스 다이어그램
sequenceDiagram
title interaction VisualReward SDK
participant A as Host App
participant B as VisualReward SDK
participant C as VisualReward 서버
participant D as WebView 화면
A->>B: initialize(appKey, ...)
B->>C: config 요청
C-->>B: config 응답
B-->>A: onSuccess()
A->>B: setUserId(userId)
A->>B: open(serviceName, ...)
B->>D: 웹뷰 열기
D->>B: 웹뷰 닫힘
B-->>A: onClose사용법
디버그 설정
initialize()전에 호출합니다.import { VisualReward } from '@tenqube/visual-reward-react-native'; VisualReward.setDebugEnabled(__DEV__);
초기화
App.tsx의useEffect등 앱 시작 시 한 번만 호출합니다.import { VisualReward } from '@tenqube/visual-reward-react-native'; import AsyncStorage from '@react-native-async-storage/async-storage'; useEffect(() => { VisualReward.initialize({ appKey: 'tq_live_xxx', storage: AsyncStorage, // config 캐싱용 (선택) timeoutMs: 5000, // 기본값 (ms) onSuccess: () => { /* SDK 준비 완료 */ }, onFailure: (e) => { /* 초기화 실패 */ }, }); }, []);config 캐싱을 사용하려면
storage에AsyncStorage를 주입합니다. 미주입 시 매번 네트워크에서 config를 fetch합니다.@react-native-async-storage/async-storage가 설치되어 있지 않다면npm install @react-native-async-storage/async-storage로 설치합니다.initialize 파라미터
| 파라미터 | 타입 | 필수 | 설명 | 기본값 | | --- | --- | --- | --- | --- | |
appKey|string| ✅ | stage별 app_key 발급 요청이 필요합니다. | | |storage|AsyncStorageLike| | config 캐싱용 AsyncStorage 구현체. 미주입 시 캐싱 없이 매번 fetch |undefined| |timeoutMs|number| | 초기화 완료 대기 시간 (ms). 초과 시INITIALIZE_TIMEOUT에러 발생 |5000| |onSuccess|() => void| | 초기화 성공 콜백 |undefined| |onFailure|(error: VisualRewardError) => void| | 초기화 실패 콜백 |undefined|
사용자 설정
로그인 후 또는 사용자가 변경될 때 호출합니다.
open()전에 반드시 호출해야 합니다.VisualReward.setUserId(user.id);
웹뷰 열기
initialize()후에 호출합니다.import { VisualReward } from '@tenqube/visual-reward-react-native'; await VisualReward.open({ serviceName: 'reward_home', locale: 'ko', extra: undefined, onClose: () => { /* 웹뷰 닫힘 */ }, });open 파라미터
| 파라미터 | 타입 | 필수 | 설명 | 기본값 | | --- | --- | --- | --- | --- | |
serviceName|string| ✅ | 사용 서비스별 serviceName 전달 예정입니다. | | |locale|string \| undefined| | BCP 47 (RFC 5646) 언어 서브태그(ISO 639-1, 2자리 소문자)를 사용 |"ko"| |extra|string \| undefined| | 포스트백 추가 데이터 (JSON serialize된 문자열) |undefined| |onClose|() => void| | 웹뷰가 닫힐 때 호출되는 콜백 |undefined| |onError|(error: VisualRewardError) => void| | 에러 발생 시 호출되는 콜백 |undefined|
에러 처리
에러 타입
| 타입 | 설명 |
| --- | --- |
| NETWORK_ERROR | 네트워크 연결 실패 |
| INITIALIZE_TIMEOUT | initialize() 호출 후 완료까지 타임아웃 |
| INVALID_APP_KEY | 유효하지 않은 앱 키 (404) |
| SERVER_ERROR | 서버 오류 (5xx) |
| PARSE_ERROR | 응답 파싱 실패 |
| NOT_INITIALIZED | initialize() 호출 없이 open() 호출 |
| USER_ID_NOT_SET | setUserId() 호출 없이 open() 호출 |
initialize 에러 처리
onFailure콜백에서 에러 타입을 분기합니다.import { VisualReward, VisualRewardError } from '@tenqube/visual-reward-react-native'; VisualReward.initialize({ appKey: 'tq_live_xxx', timeoutMs: 5000, onSuccess: () => { /* SDK 준비 완료 */ }, onFailure: (e) => { if (e instanceof VisualRewardError) { switch (e.code) { case 'NETWORK_ERROR': break; // 네트워크 연결 실패 case 'INITIALIZE_TIMEOUT': break; // 초기화 타임아웃 case 'INVALID_APP_KEY': break; // 존재하지 않는 앱 키 case 'SERVER_ERROR': break; // 서버 오류 case 'PARSE_ERROR': break; // 응답 파싱 실패 } } }, });
open 에러 처리
open()은 예외를 throw하지 않고onError콜백으로 에러를 전달합니다. 콜백에서 에러 타입을 분기합니다.import { VisualReward, VisualRewardError } from '@tenqube/visual-reward-react-native'; await VisualReward.open({ serviceName: 'reward_home', locale: 'ko', extra: undefined, onClose: () => { /* 웹뷰 닫힘 */ }, onError: (e: VisualRewardError) => { switch (e.code) { case 'NOT_INITIALIZED': break; // initialize() 미호출 case 'USER_ID_NOT_SET': break; // setUserId() 미호출 case 'INITIALIZE_TIMEOUT': break; // 초기화 대기 타임아웃 case 'NETWORK_ERROR': break; // 네트워크 연결 실패 default: break; // 기타 오류 } }, });
