메인 콘텐츠로 건너뛰기

개요

전면 광고(Interstitial Ad)는 앱의 화면 전체를 덮는 형태로 표시되는 광고입니다. 게임의 레벨 전환, 콘텐츠 페이지 전환 등 앱의 자연스러운 전환 시점에 표시하기 적합합니다.

특징

  • 전체 화면을 덮는 몰입형 광고
  • 사용자가 명시적으로 닫기 전까지 유지
  • 이미지 및 동영상 광고 지원
  • 높은 시각적 주목도
개발 환경에서는 테스트 유닛 ID를 사용하세요: PUBLIC_TEST_UNIT_ID_INTERSTITIAL

구현 방식

Adrop React Native SDK는 전면 광고를 구현하는 두 가지 방식을 제공합니다:
  1. 클래스 방식 - AdropInterstitialAd 클래스를 직접 사용
  2. Hook 방식 - useAdropInterstitialAd Hook 사용 (권장)

AdropInterstitialAd 클래스

생성자

AdropInterstitialAd 인스턴스를 생성합니다.
import { AdropInterstitialAd } from 'adrop-ads-react-native'

const interstitialAd = new AdropInterstitialAd(unitId)
unitId
string
required
광고 유닛 ID (콘솔에서 발급)

프로퍼티

isLoaded
boolean
광고가 로드되었는지 여부를 반환합니다.
if (interstitialAd.isLoaded) {
  // 광고 표시 가능
}
unitId
string
광고 유닛 ID를 반환합니다.
const unitId = interstitialAd.unitId
creativeId
string
현재 로드된 광고의 크리에이티브 ID를 반환합니다.
const creativeId = interstitialAd.creativeId
txId
string
현재 로드된 광고의 트랜잭션 ID를 반환합니다.
const txId = interstitialAd.txId
campaignId
string
현재 로드된 광고의 캠페인 ID를 반환합니다.
const campaignId = interstitialAd.campaignId
listener
AdropListener
광고 이벤트를 수신하는 리스너를 설정합니다.
interstitialAd.listener = {
  onAdReceived: (ad) => console.log('광고 수신'),
  onAdFailedToReceive: (ad, errorCode) => console.log('수신 실패', errorCode),
  // ... 기타 콜백
}

메서드

load()
() => void
광고를 요청하고 로드합니다.
interstitialAd.load()
show()
() => void
로드된 광고를 표시합니다. isLoadedtrue일 때 호출해야 합니다.
if (interstitialAd.isLoaded) {
  interstitialAd.show()
}
destroy()
() => void
광고 인스턴스를 파괴하고 리소스를 해제합니다. 컴포넌트 언마운트 시 반드시 호출해야 합니다.
useEffect(() => {
  return () => {
    interstitialAd?.destroy()
  }
}, [interstitialAd])

AdropListener 인터페이스

광고 이벤트를 수신하기 위한 콜백 인터페이스입니다.

필수 콜백

onAdReceived
(ad: AdropAd) => void
광고 수신 성공 시 호출됩니다. 이 시점에서 show()를 호출하여 광고를 표시할 수 있습니다.
onAdReceived: (ad) => {
  console.log('광고 수신 완료:', ad.unitId)
  // 광고 표시 준비 완료
}
onAdFailedToReceive
(ad: AdropAd, errorCode?: string) => void
광고 수신 실패 시 호출됩니다. 에러 코드를 통해 실패 원인을 확인할 수 있습니다.
onAdFailedToReceive: (ad, errorCode) => {
  console.log('광고 수신 실패:', errorCode)
}

선택 콜백

onAdImpression
(ad: AdropAd) => void
광고 노출이 기록되었을 때 호출됩니다.
onAdImpression: (ad) => {
  console.log('광고 노출됨')
}
onAdClicked
(ad: AdropAd) => void
사용자가 광고를 클릭했을 때 호출됩니다.
onAdClicked: (ad) => {
  console.log('광고 클릭됨')
}
onAdWillPresentFullScreen
(ad: AdropAd) => void
전면 광고가 표시되기 직전에 호출됩니다. 게임 일시정지 등의 작업을 수행할 수 있습니다.
onAdWillPresentFullScreen: (ad) => {
  console.log('광고 표시 직전')
  // 게임 일시정지, 음악 중지 등
}
onAdDidPresentFullScreen
(ad: AdropAd) => void
전면 광고가 화면에 표시된 직후 호출됩니다.
onAdDidPresentFullScreen: (ad) => {
  console.log('광고 표시 완료')
}
onAdWillDismissFullScreen
(ad: AdropAd) => void
전면 광고가 닫히기 직전에 호출됩니다.
onAdWillDismissFullScreen: (ad) => {
  console.log('광고 닫히기 직전')
}
onAdDidDismissFullScreen
(ad: AdropAd) => void
전면 광고가 닫힌 직후 호출됩니다. 다음 광고를 미리 로드하기 좋은 시점입니다.
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)
unitId
string | null
required
광고 유닛 ID. null을 전달하면 광고가 해제됩니다.

반환값

load
() => void
광고를 로드합니다. isReadytrue일 때만 동작합니다.
const handleLoad = () => {
  if (isReady) {
    load()
  }
}
show
() => void
로드된 광고를 표시합니다.
const handleShow = () => {
  if (isLoaded) {
    show()
  }
}
reset
() => void
광고 상태를 초기화하고 새 인스턴스를 생성합니다.
const handleReset = () => {
  reset()
}
isReady
boolean
광고 인스턴스가 준비되었는지 여부입니다.
isLoaded
boolean
광고가 성공적으로 로드되었는지 여부입니다.
isOpened
boolean
광고가 화면에 표시되었는지 여부입니다.
isClosed
boolean
광고가 닫혔는지 여부입니다.
isClicked
boolean
광고가 클릭되었는지 여부입니다.
errorCode
string | undefined
광고 로드 또는 표시 중 발생한 에러 코드입니다.

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_INITIALIZESDK 초기화 실패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의 뒤로가기 버튼으로 광고를 닫을 수 있습니다
  • 하드웨어 가속이 필요할 수 있습니다

다음 단계