팝업 광고(Popup Ad)는 특정 순간에 화면에 나타나는 광고 포맷입니다. 앱 실행 시, 콘텐츠 로드 완료 시, 특정 이벤트 발생 시 등 원하는 타이밍에 표시할 수 있으며, 사용자가 닫기 버튼을 누르거나 “오늘 하루 보지 않기”를 선택하여 종료할 수 있습니다.
화면 중앙 또는 하단에 표시되는 팝업 형태
이미지 및 동영상 광고 지원
닫기, 딤(배경) 클릭, “오늘 하루 보지 않기” 옵션 제공
배경색, 텍스트 색상 등 커스터마이징 가능
비침투적이면서도 효과적인 광고 경험
개발 환경에서는 테스트 유닛 ID를 사용하세요. 테스트 유닛 ID 섹션을 참고하세요.
구현 단계
팝업 광고는 다음 4단계로 구현합니다:
초기화 - AdropPopupAd 인스턴스 생성
리스너 설정 - 광고 이벤트 수신을 위한 리스너 설정
광고 로드 - 광고 요청 및 수신
광고 표시 - 화면에 광고 표시
기본 구현
AdropPopupAd 클래스는 팝업 광고를 관리하는 메인 클래스입니다.
import AdropPopupAd , { AdropPopupAdColors } from 'adrop-ads-react-native' ;
const popupAd = new AdropPopupAd (
unitId : string ,
colors ?: AdropPopupAdColors ,
useCustomClick ?: boolean
);
생성자 파라미터
팝업 광고 유닛 ID. 애드컨트롤 콘솔에서 생성한 유닛 ID를 사용합니다.
팝업 광고의 색상을 커스터마이징하는 옵션입니다.
closeTextColor: 닫기 버튼 텍스트 색상
hideForTodayTextColor: “오늘 하루 보지 않기” 텍스트 색상
backgroundColor: 팝업 배경(딤) 색상
커스텀 클릭 처리 사용 여부. true로 설정하면 광고 클릭 시 기본 브라우저 열기 대신 onAdClicked 콜백만 호출됩니다.
기본 사용법
import React , { useEffect , useState , useMemo } from 'react' ;
import { Button , View } from 'react-native' ;
import AdropPopupAd , { AdropListener } from 'adrop-ads-react-native' ;
const App : React . FC = () => {
const [ popupAd , setPopupAd ] = useState < AdropPopupAd >();
const [ isLoaded , setIsLoaded ] = useState ( false );
const listener : AdropListener = useMemo (() => ({
onAdReceived : ( ad : AdropPopupAd ) => {
console . log ( '팝업 광고 수신 완료' );
setIsLoaded ( true );
},
onAdFailedToReceive : ( _ : AdropPopupAd , errorCode : any ) => {
console . log ( '팝업 광고 수신 실패:' , errorCode );
},
onAdClicked : ( ad : AdropPopupAd ) => {
console . log ( '팝업 광고 클릭' );
// 광고 클릭 시 팝업 닫기
ad . close ();
},
}), []);
useEffect (() => {
// 1. 팝업 광고 생성
const ad = new AdropPopupAd ( 'YOUR_POPUP_UNIT_ID' );
ad . listener = listener ;
setPopupAd ( ad );
// 2. 광고 로드
ad . load ();
// 컴포넌트 언마운트 시 정리
return () => {
ad . destroy ();
};
}, [ listener ]);
// 3. 광고 표시
const showAd = () => {
if ( popupAd && isLoaded ) {
popupAd . show ();
}
};
return (
< View >
< Button
title = "팝업 광고 표시"
onPress = { showAd }
disabled = {! isLoaded }
/>
</ View >
);
};
export default App ;
AdropListener 인터페이스
팝업 광고의 이벤트를 수신하기 위한 리스너 인터페이스입니다.
필수 콜백
onAdReceived
(ad: AdropPopupAd) => void
광고 수신 성공 시 호출됩니다. 이 시점에서 show()를 호출하여 광고를 표시할 수 있습니다.
onAdFailedToReceive
(ad: AdropPopupAd, errorCode?: any) => void
광고 수신 실패 시 호출됩니다. 에러 코드를 통해 실패 원인을 확인할 수 있습니다.
선택 콜백
onAdImpression
(ad: AdropPopupAd) => void
광고 노출이 기록되었을 때 호출됩니다.
onAdClicked
(ad: AdropPopupAd) => void
사용자가 광고를 클릭했을 때 호출됩니다. 이 콜백에서 ad.close()를 호출하여 팝업을 닫을 수 있습니다.
onAdWillPresentFullScreen
(ad: AdropPopupAd) => void
팝업 광고가 표시되기 직전에 호출됩니다.
onAdDidPresentFullScreen
(ad: AdropPopupAd) => void
팝업 광고가 화면에 표시된 직후 호출됩니다.
onAdWillDismissFullScreen
(ad: AdropPopupAd) => void
팝업 광고가 닫히기 직전에 호출됩니다.
onAdDidDismissFullScreen
(ad: AdropPopupAd) => void
팝업 광고가 닫힌 직후 호출됩니다. 다음 광고를 미리 로드하기 좋은 시점입니다.
onAdFailedToShowFullScreen
(ad: AdropPopupAd, errorCode?: any) => void
광고 표시 실패 시 호출됩니다. 에러 코드를 통해 실패 원인을 확인할 수 있습니다.
리스너 구현 예시
const listener : AdropListener = useMemo (() => ({
// 광고 수신 성공
onAdReceived : ( ad : AdropPopupAd ) => {
console . log ( '팝업 광고 수신 완료' );
console . log ( 'Creative ID:' , ad . creativeId );
console . log ( 'Campaign ID:' , ad . campaignId );
// 광고가 준비되면 자동으로 표시
ad . show ();
},
// 광고 수신 실패
onAdFailedToReceive : ( ad : AdropPopupAd , errorCode ?: any ) => {
console . log ( '팝업 광고 수신 실패:' , errorCode );
},
// 광고 노출
onAdImpression : ( ad : AdropPopupAd ) => {
console . log ( '팝업 광고 노출됨' );
console . log ( 'TX ID:' , ad . txId );
console . log ( 'Destination URL:' , ad . destinationURL );
},
// 광고 클릭
onAdClicked : ( ad : AdropPopupAd ) => {
console . log ( '팝업 광고 클릭:' , ad . destinationURL );
// 클릭 시 팝업 닫기
ad . close ();
},
// 팝업 표시 직전
onAdWillPresentFullScreen : ( ad : AdropPopupAd ) => {
console . log ( '팝업 광고 표시 직전' );
},
// 팝업 표시 완료
onAdDidPresentFullScreen : ( ad : AdropPopupAd ) => {
console . log ( '팝업 광고 표시 완료' );
},
// 팝업 닫히기 직전
onAdWillDismissFullScreen : ( ad : AdropPopupAd ) => {
console . log ( '팝업 광고 닫히기 직전' );
},
// 팝업 닫힘
onAdDidDismissFullScreen : ( ad : AdropPopupAd ) => {
console . log ( '팝업 광고 닫힘' );
// 다음 광고 미리 로드
loadNextAd ();
},
// 팝업 표시 실패
onAdFailedToShowFullScreen : ( ad : AdropPopupAd , errorCode ?: any ) => {
console . log ( '팝업 광고 표시 실패:' , errorCode );
},
}), []);
메서드
load()
광고를 요청하고 로드합니다.
show()
로드된 광고를 화면에 표시합니다. onAdReceived 콜백이 호출된 후에만 호출할 수 있습니다.
show()는 광고가 로드된 상태(isLoaded === true)에서만 호출해야 합니다.
close()
현재 표시 중인 팝업 광고를 닫습니다. 주로 onAdClicked 콜백에서 사용됩니다.
destroy()
광고 인스턴스를 정리하고 리소스를 해제합니다. 컴포넌트 언마운트 시 반드시 호출해야 합니다.
useEffect (() => {
const ad = new AdropPopupAd ( 'YOUR_UNIT_ID' );
setPopupAd ( ad );
return () => {
ad . destroy ();
};
}, []);
광고 속성
팝업 광고 객체에서 다음 속성들을 사용할 수 있습니다:
커스터마이징
색상 설정
AdropPopupAdColors 타입을 사용하여 팝업 광고의 색상을 커스터마이징할 수 있습니다.
import AdropPopupAd , { AdropPopupAdColors } from 'adrop-ads-react-native' ;
// 색상 옵션 정의
const customColors : AdropPopupAdColors = {
closeTextColor: '#FFFFFF' , // 닫기 버튼 색상
hideForTodayTextColor: '#456789' , // "오늘 하루 보지 않기" 색상
backgroundColor: 'rgba(53, 255, 63, 0.3)' , // 배경(딤) 색상
};
// 팝업 광고 생성 시 색상 적용
const popupAd = new AdropPopupAd (
'YOUR_POPUP_UNIT_ID' ,
customColors
);
닫기 버튼 텍스트 색상. HEX 색상 코드 또는 RGBA 형식을 지원합니다.
“오늘 하루 보지 않기” 텍스트 색상. HEX 색상 코드 또는 RGBA 형식을 지원합니다.
팝업 배경(딤) 색상. HEX 색상 코드 또는 RGBA 형식을 지원합니다. 투명도 조절이 가능합니다.
커스텀 클릭 처리
광고 클릭 시 기본 브라우저 열기 대신 커스텀 처리를 하려면 useCustomClick 파라미터를 사용하세요.
const listener : AdropListener = useMemo (() => ({
onAdReceived : ( ad : AdropPopupAd ) => {
ad . show ();
},
onAdFailedToReceive : ( _ : AdropPopupAd , errorCode : any ) => {
console . log ( '광고 수신 실패:' , errorCode );
},
onAdClicked : ( ad : AdropPopupAd ) => {
// 커스텀 클릭 처리
console . log ( '광고 클릭됨:' , ad . destinationURL );
// 원하는 방식으로 URL 처리
// 예: In-App 브라우저로 열기
openInAppBrowser ( ad . destinationURL );
// 팝업 닫기
ad . close ();
},
}), []);
// useCustomClick을 true로 설정
const popupAd = new AdropPopupAd (
'YOUR_POPUP_UNIT_ID' ,
undefined , // colors
true // useCustomClick
);
popupAd . listener = listener ;
구현 예제
완전한 구현 예제
import React , { useCallback , useEffect , useMemo , useState } from 'react' ;
import { Button , StyleSheet , Text , View } from 'react-native' ;
import AdropPopupAd , {
AdropListener ,
AdropPopupAdColors ,
} from 'adrop-ads-react-native' ;
const PopupAdExample : React . FC = () => {
const [ popupAd , setPopupAd ] = useState < AdropPopupAd >();
const [ isLoaded , setIsLoaded ] = useState ( false );
const [ errorCode , setErrorCode ] = useState ( '' );
// 리스너 정의
const listener : AdropListener = useMemo (() => ({
onAdReceived : ( ad : AdropPopupAd ) => {
console . log ( '팝업 광고 수신 완료' );
setIsLoaded ( true );
setErrorCode ( '' );
},
onAdFailedToReceive : ( _ : AdropPopupAd , error : any ) => {
console . log ( '팝업 광고 수신 실패:' , error );
setErrorCode ( error );
setIsLoaded ( false );
},
onAdImpression : ( ad : AdropPopupAd ) => {
console . log ( '팝업 광고 노출:' , ad . txId , ad . campaignId );
},
onAdClicked : ( ad : AdropPopupAd ) => {
console . log ( '팝업 광고 클릭:' , ad . destinationURL );
// 클릭 시 팝업 닫기
ad . close ();
},
onAdDidPresentFullScreen : ( ad : AdropPopupAd ) => {
console . log ( '팝업 광고 표시됨' );
},
onAdDidDismissFullScreen : ( ad : AdropPopupAd ) => {
console . log ( '팝업 광고 닫힘' );
// 다음 광고 미리 로드
ad . load ();
},
onAdFailedToShowFullScreen : ( _ : AdropPopupAd , error : any ) => {
console . log ( '팝업 광고 표시 실패:' , error );
setErrorCode ( error );
},
}), []);
// 팝업 광고 초기화
const initializeAd = useCallback (( unitId : string ) => {
// 색상 커스터마이징
const customColors : AdropPopupAdColors = {
hideForTodayTextColor: '#456789' ,
backgroundColor: 'rgba(53, 255, 63, 0.3)' ,
};
// 팝업 광고 생성
const ad = new AdropPopupAd ( unitId , customColors );
ad . listener = listener ;
setPopupAd (( prev ) => {
prev ?. destroy ();
return ad ;
});
}, [ listener ]);
// 컴포넌트 마운트 시 초기화
useEffect (() => {
initializeAd ( 'YOUR_POPUP_UNIT_ID' );
}, [ initializeAd ]);
// 컴포넌트 언마운트 시 정리
useEffect (() => {
return () => {
popupAd ?. destroy ();
};
}, [ popupAd ]);
// 광고 로드
const loadAd = () => {
popupAd ?. load ();
setIsLoaded ( false );
};
// 광고 표시
const showAd = () => {
if ( popupAd && isLoaded ) {
popupAd . show ();
}
};
return (
< View style = {styles. container } >
< Button title = "광고 로드" onPress = { loadAd } />
< Button
title = "광고 표시"
onPress = { showAd }
disabled = {! isLoaded }
/>
{ errorCode && (
< Text style = {styles. error } > 에러 코드 : { errorCode } </ Text >
)}
</ View >
);
};
const styles = StyleSheet . create ({
container: {
flex: 1 ,
alignItems: 'center' ,
justifyContent: 'center' ,
gap: 10 ,
},
error: {
color: 'red' ,
marginTop: 10 ,
},
});
export default PopupAdExample ;
”오늘 하루 보지 않기” 구현
사용자가 “오늘 하루 보지 않기”를 선택했을 때 적절히 처리하는 방법입니다.
import AsyncStorage from '@react-native-async-storage/async-storage' ;
const POPUP_AD_HIDDEN_KEY = 'popup_ad_hidden_date' ;
// 오늘 광고를 표시할 수 있는지 확인
const canShowAdToday = async () : Promise < boolean > => {
try {
const lastHiddenDate = await AsyncStorage . getItem ( POPUP_AD_HIDDEN_KEY );
if ( ! lastHiddenDate ) return true ;
const hiddenDate = new Date ( parseInt ( lastHiddenDate , 10 ));
const today = new Date ();
// 저장된 날짜가 오늘이 아니면 표시 가능
return (
hiddenDate . getFullYear () !== today . getFullYear () ||
hiddenDate . getMonth () !== today . getMonth () ||
hiddenDate . getDate () !== today . getDate ()
);
} catch ( error ) {
console . error ( 'Error checking popup ad visibility:' , error );
return true ;
}
};
// "오늘 하루 보지 않기" 클릭 시 날짜 저장
const saveHiddenDate = async () => {
try {
await AsyncStorage . setItem (
POPUP_AD_HIDDEN_KEY ,
Date . now (). toString ()
);
console . log ( '오늘 하루 팝업 광고를 표시하지 않습니다' );
} catch ( error ) {
console . error ( 'Error saving popup ad hidden date:' , error );
}
};
// 사용 예시
const PopupAdWithHideToday : React . FC = () => {
const [ popupAd , setPopupAd ] = useState < AdropPopupAd >();
useEffect (() => {
const initAd = async () => {
// 오늘 표시 가능한지 확인
const canShow = await canShowAdToday ();
if ( ! canShow ) {
console . log ( '오늘은 광고를 표시하지 않습니다' );
return ;
}
const ad = new AdropPopupAd ( 'YOUR_POPUP_UNIT_ID' );
ad . listener = {
onAdReceived : ( ad : AdropPopupAd ) => {
ad . show ();
},
onAdFailedToReceive : ( _ : AdropPopupAd , error : any ) => {
console . log ( '광고 수신 실패:' , error );
},
onAdDidDismissFullScreen : async ( ad : AdropPopupAd ) => {
// 사용자가 "오늘 하루 보지 않기"를 선택했는지는
// 네이티브 SDK에서 자동으로 처리됩니다.
// 필요시 추가 로직 구현
},
};
setPopupAd ( ad );
ad . load ();
};
initAd ();
return () => {
popupAd ?. destroy ();
};
}, []);
return < View />;
};
테스트 유닛 ID
개발 및 테스트 시 다음 테스트 유닛 ID를 사용하세요.
광고 타입 테스트 유닛 ID 팝업 (하단 이미지) PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM팝업 (중앙 이미지) PUBLIC_TEST_UNIT_ID_POPUP_CENTER팝업 비디오 (하단 16:9) PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM_VIDEO_16_9팝업 비디오 (하단 9:16) PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM_VIDEO_9_16팝업 비디오 (중앙 16:9) PUBLIC_TEST_UNIT_ID_POPUP_CENTER_VIDEO_16_9팝업 비디오 (중앙 9:16) PUBLIC_TEST_UNIT_ID_POPUP_CENTER_VIDEO_9_16
테스트 광고 사용 예시
import { Platform } from 'react-native' ;
// 개발/프로덕션 환경 분리
const POPUP_UNIT_ID = __DEV__
? 'PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM' // 테스트 유닛 ID
: 'YOUR_PRODUCTION_UNIT_ID' ; // 실제 유닛 ID
const popupAd = new AdropPopupAd ( POPUP_UNIT_ID );
실제 배포 시에는 반드시 애드컨트롤 콘솔에서 생성한 실제 유닛 ID를 사용하세요.
에러 처리
광고 로드 또는 표시 실패 시 에러 코드를 확인하여 적절히 처리하세요.
const listener : AdropListener = {
onAdFailedToReceive : ( ad : AdropPopupAd , errorCode ?: any ) => {
console . error ( '광고 수신 실패:' , errorCode );
switch ( errorCode ) {
case 'NETWORK_ERROR' :
// 네트워크 오류 처리
console . log ( '네트워크 연결을 확인해주세요' );
break ;
case 'NO_FILL' :
// 광고 인벤토리 부족
console . log ( '현재 표시할 수 있는 광고가 없습니다' );
break ;
case 'INVALID_UNIT_ID' :
// 잘못된 유닛 ID
console . log ( '광고 유닛 ID를 확인해주세요' );
break ;
default :
console . log ( '광고를 불러올 수 없습니다' );
}
},
onAdFailedToShowFullScreen : ( ad : AdropPopupAd , errorCode ?: any ) => {
console . error ( '광고 표시 실패:' , errorCode );
// 다음에 다시 시도
setTimeout (() => {
ad . load ();
}, 30000 ); // 30초 후 재시도
},
};
모범 사례
1. 적절한 표시 시점
팝업 광고는 다음 시점에 표시하는 것이 효과적입니다:
// ✅ 좋은 예: 앱 시작 시
useEffect (() => {
const ad = new AdropPopupAd ( 'YOUR_UNIT_ID' );
ad . listener = {
onAdReceived : ( ad ) => ad . show (),
onAdFailedToReceive : ( _ , error ) => console . log ( error ),
};
ad . load ();
return () => ad . destroy ();
}, []);
// ✅ 좋은 예: 콘텐츠 로드 완료 시
const onContentLoaded = () => {
if ( shouldShowPopupAd ()) {
popupAd ?. show ();
}
};
// ✅ 좋은 예: 특정 이벤트 완료 시
const onAchievementUnlocked = () => {
popupAd ?. show ();
};
// ❌ 나쁜 예: 사용자가 작업 중일 때
const onUserTyping = () => {
popupAd ?. show (); // 사용자 경험 저해
};
2. 빈도 제한
팝업 광고를 너무 자주 표시하지 마세요.
import AsyncStorage from '@react-native-async-storage/async-storage' ;
const LAST_SHOWN_KEY = 'popup_ad_last_shown' ;
const MINIMUM_INTERVAL = 3600000 ; // 1시간 (밀리초)
// 광고를 표시할 수 있는지 확인
const canShowAd = async () : Promise < boolean > => {
try {
const lastShown = await AsyncStorage . getItem ( LAST_SHOWN_KEY );
if ( ! lastShown ) return true ;
const currentTime = Date . now ();
const lastShownTime = parseInt ( lastShown , 10 );
return currentTime - lastShownTime >= MINIMUM_INTERVAL ;
} catch ( error ) {
return true ;
}
};
// 광고 표시 기록
const recordAdShown = async () => {
try {
await AsyncStorage . setItem ( LAST_SHOWN_KEY , Date . now (). toString ());
} catch ( error ) {
console . error ( 'Error recording ad shown:' , error );
}
};
// 사용
const showAdIfAllowed = async () => {
if ( await canShowAd ()) {
popupAd ?. show ();
await recordAdShown ();
}
};
3. 광고 미리 로드
사용자 경험을 위해 광고를 미리 로드하세요.
const [ isAdReady , setIsAdReady ] = useState ( false );
useEffect (() => {
// 앱 시작 시 미리 로드
const ad = new AdropPopupAd ( 'YOUR_UNIT_ID' );
ad . listener = {
onAdReceived : () => setIsAdReady ( true ),
onAdFailedToReceive : ( _ , error ) => console . log ( error ),
};
ad . load ();
setPopupAd ( ad );
return () => ad . destroy ();
}, []);
// 원하는 시점에 즉시 표시
const showPopupNow = () => {
if ( isAdReady ) {
popupAd ?. show ();
}
};
4. 메모리 관리
컴포넌트 언마운트 시 반드시 광고를 정리하세요.
useEffect (() => {
const ad = new AdropPopupAd ( 'YOUR_UNIT_ID' );
setPopupAd ( ad );
// 정리 함수
return () => {
ad . destroy ();
};
}, []);
5. 클릭 시 팝업 닫기
광고 클릭 시 팝업을 닫아 사용자 경험을 개선하세요.
const listener : AdropListener = {
onAdClicked : ( ad : AdropPopupAd ) => {
console . log ( '광고 클릭:' , ad . destinationURL );
// 클릭 시 팝업 자동 닫기
ad . close ();
},
};
문제 해결
광고가 표시되지 않음
SDK가 초기화되었는지 확인
유닛 ID가 올바른지 확인
네트워크 연결 상태 확인
테스트 환경에서는 테스트 유닛 ID 사용
에러 코드를 확인하여 원인 파악
광고 인벤토리 부족 시 나중에 재시도
네이티브 SDK가 올바르게 연동되었는지 확인
show() 호출 후 아무 일도 일어나지 않음
onAdReceived 콜백 이후에 show()를 호출했는지 확인
isLoaded 속성을 확인하여 광고가 로드되었는지 확인
네이티브 모듈이 올바르게 연결되었는지 확인
메모리 누수
// ✅ 좋은 예: 정리 함수 사용
useEffect (() => {
const ad = new AdropPopupAd ( 'YOUR_UNIT_ID' );
setPopupAd ( ad );
return () => {
ad . destroy (); // 반드시 호출
};
}, []);
// ❌ 나쁜 예: 정리하지 않음
useEffect (() => {
const ad = new AdropPopupAd ( 'YOUR_UNIT_ID' );
setPopupAd ( ad );
// destroy() 호출 없음 - 메모리 누수!
}, []);
관련 문서