전면 광고(Interstitial Ad)는 앱의 화면 전체를 덮는 형태로 표시되는 광고입니다. 게임의 레벨 전환, 콘텐츠 페이지 전환 등 앱의 자연스러운 전환 시점에 표시하기 적합합니다.
- 전체 화면을 덮는 몰입형 광고
- 사용자가 명시적으로 닫기 전까지 유지
- 이미지 및 동영상 광고 지원
- 높은 시각적 주목도
개발 환경에서는 테스트 유닛 ID를 사용하세요: PUBLIC_TEST_UNIT_ID_INTERSTITIAL
구현 방식
Adrop React Native SDK는 전면 광고를 구현하는 두 가지 방식을 제공합니다:
- 클래스 방식 - AdropInterstitialAd 클래스를 직접 사용
- Hook 방식 - useAdropInterstitialAd Hook 사용 (권장)
AdropInterstitialAd 클래스
생성자
AdropInterstitialAd 인스턴스를 생성합니다.
import { AdropInterstitialAd } from 'adrop-ads-react-native'
const interstitialAd = new AdropInterstitialAd(unitId)
프로퍼티
광고가 로드되었는지 여부를 반환합니다.if (interstitialAd.isLoaded) {
// 광고 표시 가능
}
광고 유닛 ID를 반환합니다.const unitId = interstitialAd.unitId
현재 로드된 광고의 크리에이티브 ID를 반환합니다.const creativeId = interstitialAd.creativeId
현재 로드된 광고의 트랜잭션 ID를 반환합니다.const txId = interstitialAd.txId
현재 로드된 광고의 캠페인 ID를 반환합니다.const campaignId = interstitialAd.campaignId
광고 이벤트를 수신하는 리스너를 설정합니다.interstitialAd.listener = {
onAdReceived: (ad) => console.log('광고 수신'),
onAdFailedToReceive: (ad, errorCode) => console.log('수신 실패', errorCode),
// ... 기타 콜백
}
메서드
로드된 광고를 표시합니다. isLoaded가 true일 때 호출해야 합니다.if (interstitialAd.isLoaded) {
interstitialAd.show()
}
광고 인스턴스를 파괴하고 리소스를 해제합니다. 컴포넌트 언마운트 시 반드시 호출해야 합니다.useEffect(() => {
return () => {
interstitialAd?.destroy()
}
}, [interstitialAd])
AdropListener 인터페이스
광고 이벤트를 수신하기 위한 콜백 인터페이스입니다.
필수 콜백
광고 수신 성공 시 호출됩니다. 이 시점에서 show()를 호출하여 광고를 표시할 수 있습니다.onAdReceived: (ad) => {
console.log('광고 수신 완료:', ad.unitId)
// 광고 표시 준비 완료
}
onAdFailedToReceive
(ad: AdropAd, errorCode?: string) => void
광고 수신 실패 시 호출됩니다. 에러 코드를 통해 실패 원인을 확인할 수 있습니다.onAdFailedToReceive: (ad, errorCode) => {
console.log('광고 수신 실패:', errorCode)
}
선택 콜백
광고 노출이 기록되었을 때 호출됩니다.onAdImpression: (ad) => {
console.log('광고 노출됨')
}
사용자가 광고를 클릭했을 때 호출됩니다.onAdClicked: (ad) => {
console.log('광고 클릭됨')
}
onAdWillPresentFullScreen
전면 광고가 표시되기 직전에 호출됩니다. 게임 일시정지 등의 작업을 수행할 수 있습니다.onAdWillPresentFullScreen: (ad) => {
console.log('광고 표시 직전')
// 게임 일시정지, 음악 중지 등
}
전면 광고가 화면에 표시된 직후 호출됩니다.onAdDidPresentFullScreen: (ad) => {
console.log('광고 표시 완료')
}
onAdWillDismissFullScreen
전면 광고가 닫히기 직전에 호출됩니다.onAdWillDismissFullScreen: (ad) => {
console.log('광고 닫히기 직전')
}
전면 광고가 닫힌 직후 호출됩니다. 다음 광고를 미리 로드하기 좋은 시점입니다.onAdDidDismissFullScreen: (ad) => {
console.log('광고 닫힘')
// 게임 재개, 다음 광고 로드 등
}
onAdFailedToShowFullScreen
(ad: AdropAd, errorCode?: string) => void
광고 표시 실패 시 호출됩니다. 에러 코드를 통해 실패 원인을 확인할 수 있습니다.onAdFailedToShowFullScreen: (ad, errorCode) => {
console.log('광고 표시 실패:', errorCode)
}
클래스 방식 구현 예제
AdropInterstitialAd 클래스를 직접 사용하는 방식입니다.
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { Button, StyleSheet, Text, View } from 'react-native'
import { AdropInterstitialAd, AdropListener } from 'adrop-ads-react-native'
const InterstitialAdScreen: React.FC = () => {
const [interstitialAd, setInterstitialAd] = useState<AdropInterstitialAd>()
const [isLoaded, setIsLoaded] = useState(false)
const [errorCode, setErrorCode] = useState('')
// 광고 이벤트 리스너 설정
const listener: AdropListener = useMemo(() => ({
onAdReceived: (ad) => {
console.log('전면 광고 수신 완료:', ad.unitId)
setIsLoaded(true)
setErrorCode('')
},
onAdFailedToReceive: (ad, error) => {
console.log('전면 광고 수신 실패:', error)
setErrorCode(error || 'Unknown error')
setIsLoaded(false)
},
onAdClicked: (ad) => {
console.log('전면 광고 클릭됨')
},
onAdImpression: (ad) => {
console.log('전면 광고 노출됨')
},
onAdWillPresentFullScreen: (ad) => {
console.log('전면 광고 표시 직전')
// 게임 일시정지, 음악 중지 등
},
onAdDidPresentFullScreen: (ad) => {
console.log('전면 광고 표시 완료')
},
onAdWillDismissFullScreen: (ad) => {
console.log('전면 광고 닫히기 직전')
},
onAdDidDismissFullScreen: (ad) => {
console.log('전면 광고 닫힘')
setIsLoaded(false)
// 게임 재개, 다음 광고 미리 로드 등
},
onAdFailedToShowFullScreen: (ad, error) => {
console.log('전면 광고 표시 실패:', error)
setErrorCode(error || 'Unknown error')
setIsLoaded(false)
},
}), [])
// 광고 인스턴스 초기화
useEffect(() => {
const ad = new AdropInterstitialAd('YOUR_UNIT_ID')
ad.listener = listener
setInterstitialAd(ad)
// 컴포넌트 언마운트 시 정리
return () => {
ad.destroy()
}
}, [listener])
// 광고 로드
const loadAd = useCallback(() => {
interstitialAd?.load()
}, [interstitialAd])
// 광고 표시
const showAd = useCallback(() => {
if (interstitialAd?.isLoaded) {
interstitialAd.show()
} else {
console.log('광고가 아직 로드되지 않았습니다')
}
}, [interstitialAd])
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,
justifyContent: 'center',
alignItems: 'center',
gap: 16,
},
error: {
color: 'red',
marginTop: 16,
},
})
export default InterstitialAdScreen
useAdropInterstitialAd Hook
React Hook을 사용하여 전면 광고를 더 간편하게 구현할 수 있습니다.
Hook 사용법
import { useAdropInterstitialAd } from 'adrop-ads-react-native'
const { load, show, reset, isLoaded, isOpened, isClosed, isClicked, errorCode, isReady } =
useAdropInterstitialAd(unitId)
광고 유닛 ID. null을 전달하면 광고가 해제됩니다.
반환값
광고를 로드합니다. isReady가 true일 때만 동작합니다.const handleLoad = () => {
if (isReady) {
load()
}
}
로드된 광고를 표시합니다.const handleShow = () => {
if (isLoaded) {
show()
}
}
광고 상태를 초기화하고 새 인스턴스를 생성합니다.const handleReset = () => {
reset()
}
광고 로드 또는 표시 중 발생한 에러 코드입니다.
Hook 방식 구현 예제
useAdropInterstitialAd Hook을 사용하는 방식입니다 (권장).
import React, { useCallback, useMemo } from 'react'
import { Button, StyleSheet, Text, View } from 'react-native'
import { useAdropInterstitialAd } from 'adrop-ads-react-native'
const InterstitialAdScreen: React.FC = () => {
const unitId = 'YOUR_UNIT_ID'
const {
load,
show,
reset,
isLoaded,
isOpened,
isClosed,
isClicked,
errorCode,
isReady
} = useAdropInterstitialAd(unitId)
// 광고 로드
const handleLoad = useCallback(() => {
if (isReady) {
load()
}
}, [isReady, load])
// 광고 표시
const handleShow = useCallback(() => {
if (isLoaded) {
show()
}
}, [isLoaded, show])
// 광고 리셋
const handleReset = useCallback(() => {
reset()
}, [reset])
return (
<View style={styles.container}>
<Button
title="광고 로드"
onPress={handleLoad}
disabled={!isReady}
/>
<Button
title="광고 표시"
onPress={handleShow}
disabled={!isLoaded}
/>
<Button
title="광고 리셋"
onPress={handleReset}
disabled={!(isOpened || errorCode)}
/>
{/* 상태 표시 */}
<View style={styles.statusContainer}>
<Text>준비됨: {isReady ? '예' : '아니오'}</Text>
<Text>로드됨: {isLoaded ? '예' : '아니오'}</Text>
<Text>표시됨: {isOpened ? '예' : '아니오'}</Text>
<Text>닫힘: {isClosed ? '예' : '아니오'}</Text>
<Text>클릭됨: {isClicked ? '예' : '아니오'}</Text>
</View>
{errorCode && (
<Text style={styles.error}>오류: {errorCode}</Text>
)}
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
gap: 16,
},
statusContainer: {
marginTop: 24,
padding: 16,
backgroundColor: '#f0f0f0',
borderRadius: 8,
},
error: {
color: 'red',
marginTop: 16,
},
})
export default InterstitialAdScreen
테스트 유닛 ID
개발 및 테스트 환경에서는 반드시 테스트 유닛 ID를 사용하세요.
// 테스트용
const TEST_UNIT_ID = 'PUBLIC_TEST_UNIT_ID_INTERSTITIAL'
// 개발/프로덕션 환경 분리
const unitId = __DEV__
? 'PUBLIC_TEST_UNIT_ID_INTERSTITIAL'
: 'YOUR_PRODUCTION_UNIT_ID'
프로덕션 빌드에서는 반드시 실제 유닛 ID를 사용해야 합니다. 테스트 유닛 ID로 발생한 수익은 정산되지 않습니다.
에러 처리
광고 로드 및 표시 중 발생할 수 있는 에러를 적절히 처리해야 합니다.
에러 코드
| 에러 코드 | 설명 | 대응 방법 |
|---|
ERROR_CODE_NETWORK | 네트워크 오류 | 네트워크 연결 확인 후 재시도 |
ERROR_CODE_INTERNAL | 내부 오류 | 재시도 또는 고객 지원 문의 |
ERROR_CODE_INITIALIZE | SDK 초기화 실패 | SDK 초기화 코드 확인 |
ERROR_CODE_INVALID_UNIT | 유효하지 않은 유닛 ID | 유닛 ID 확인 |
ERROR_CODE_AD_NO_FILL | 광고 인벤토리 부족 | 정상, 나중에 재시도 |
ERROR_CODE_AD_LOADING | 이미 로드 중 | 로드 완료 후 재시도 |
ERROR_CODE_AD_EMPTY | 로드된 광고 없음 | 광고 로드 후 표시 |
ERROR_CODE_AD_SHOWN | 이미 표시된 광고 | 새 광고 로드 필요 |
에러 처리 예제
const { load, show, errorCode, isLoaded } = useAdropInterstitialAd(unitId)
useEffect(() => {
if (errorCode) {
switch (errorCode) {
case 'ERROR_CODE_NETWORK':
console.log('네트워크 오류: 연결 확인 필요')
// 30초 후 재시도
setTimeout(() => load(), 30000)
break
case 'ERROR_CODE_AD_NO_FILL':
console.log('표시할 광고 없음')
// 광고 없이 계속 진행
break
case 'ERROR_CODE_INVALID_UNIT':
console.error('유효하지 않은 유닛 ID')
break
default:
console.log('광고 오류:', errorCode)
break
}
}
}, [errorCode, load])
모범 사례
1. 적절한 표시 시점
앱의 자연스러운 전환 시점에 광고를 표시하세요.
// ✅ 좋은 예: 게임 레벨 전환
const handleLevelComplete = () => {
saveProgress()
if (isLoaded) {
show() // 자연스러운 전환 시점
}
navigateToNextLevel()
}
// ✅ 좋은 예: 콘텐츠 읽기 완료
const handleArticleFinished = () => {
if (isLoaded) {
show()
}
}
// ❌ 나쁜 예: 사용자 액션 중간
const handleButtonClick = () => {
show() // 사용자 경험 저해
performAction()
}
2. 사전 로드
광고를 미리 로드하여 사용자 대기 시간을 최소화하세요.
const InterstitialAdScreen: React.FC = () => {
const { load, show, isLoaded, isClosed } = useAdropInterstitialAd(unitId)
// 컴포넌트 마운트 시 광고 미리 로드
useEffect(() => {
load()
}, [load])
// 광고 닫힌 후 다음 광고 미리 로드
useEffect(() => {
if (isClosed) {
load()
}
}, [isClosed, load])
return (
// ...
)
}
3. 빈도 제한
너무 자주 광고를 표시하지 않도록 제한하세요.
const InterstitialAdScreen: React.FC = () => {
const { show, isLoaded } = useAdropInterstitialAd(unitId)
const [lastShownTime, setLastShownTime] = useState(0)
const MIN_INTERVAL = 3 * 60 * 1000 // 3분
const showAdWithFrequencyLimit = useCallback(() => {
const now = Date.now()
if (now - lastShownTime < MIN_INTERVAL) {
console.log('광고 표시 간격이 너무 짧습니다')
return
}
if (isLoaded) {
show()
setLastShownTime(now)
}
}, [isLoaded, show, lastShownTime])
return (
// ...
)
}
4. 게임 일시정지 처리
클래스 방식에서 리스너를 사용하여 게임 상태를 관리하세요.
const listener: AdropListener = useMemo(() => ({
onAdWillPresentFullScreen: (ad) => {
// 게임 일시정지
pauseGame()
pauseBackgroundMusic()
},
onAdDidDismissFullScreen: (ad) => {
// 게임 재개
resumeGame()
resumeBackgroundMusic()
},
}), [])
5. 메모리 관리
컴포넌트 언마운트 시 반드시 리소스를 해제하세요.
// Hook 방식 - 자동 관리됨
const { load, show } = useAdropInterstitialAd(unitId)
// 클래스 방식 - 수동 정리 필요
useEffect(() => {
const ad = new AdropInterstitialAd(unitId)
setInterstitialAd(ad)
return () => {
ad.destroy() // 필수!
}
}, [unitId])
플랫폼별 고려사항
iOS
- iOS에서는 앱이 백그라운드로 이동할 때 광고가 자동으로 닫힙니다
onAdDidDismissFullScreen 콜백이 호출됩니다
Android
- Android의 뒤로가기 버튼으로 광고를 닫을 수 있습니다
- 하드웨어 가속이 필요할 수 있습니다
다음 단계