전면 광고(Interstitial Ad)는 앱의 화면 전체를 덮는 형태로 표시되는 광고입니다. 게임의 레벨 전환, 콘텐츠 페이지 전환 등 앱의 자연스러운 전환 시점에 표시하기 적합합니다.
전체 화면을 덮는 몰입형 광고
사용자가 명시적으로 닫기 전까지 유지
이미지 및 동영상 광고 지원
높은 시각적 주목도
개발 환경에서는 테스트 유닛 ID를 사용하세요: PUBLIC_TEST_UNIT_ID_INTERSTITIAL
구현 단계
전면 광고는 다음 4단계로 구현합니다:
초기화 - AdropInterstitialAd 인스턴스 생성
델리게이트 설정 - 광고 이벤트 수신을 위한 델리게이트 설정
광고 로드 - 광고 요청 및 수신
광고 표시 - 화면에 광고 표시
UIKit 구현
기본 구현
import AdropAds
class ViewController : UIViewController {
private var interstitialAd: AdropInterstitialAd ?
override func viewDidLoad () {
super . viewDidLoad ()
loadInterstitialAd ()
}
// 1. 광고 초기화 및 로드
private func loadInterstitialAd () {
interstitialAd = AdropInterstitialAd ( unitId : "YOUR_UNIT_ID" )
interstitialAd ? . delegate = self
interstitialAd ? . load ()
}
// 2. 광고 표시
private func showInterstitialAd () {
guard let interstitialAd = interstitialAd,
interstitialAd.isLoaded else { return }
interstitialAd. show ( fromRootViewController : self )
}
}
isLoaded 프로퍼티
광고가 로드되었는지 확인하는 프로퍼티입니다. show() 호출 전에 이 값을 확인하는 것이 좋습니다.
if interstitialAd ? .isLoaded == true {
interstitialAd ? . show ( fromRootViewController : self )
}
델리게이트 구현
extension ViewController : AdropInterstitialAdDelegate {
// 광고 수신 성공 (필수)
func onAdReceived ( _ ad : AdropInterstitialAd) {
print ( "전면 광고 수신 완료" )
// 광고가 준비되면 표시
showInterstitialAd ()
}
// 광고 수신 실패 (필수)
func onAdFailedToReceive ( _ ad : AdropInterstitialAd, _ errorCode : AdropErrorCode) {
print ( "전면 광고 수신 실패: \( errorCode ) " )
}
// 광고 노출 (선택)
func onAdImpression ( _ ad : AdropInterstitialAd) {
print ( "전면 광고 노출" )
}
// 광고 클릭 (선택)
func onAdClicked ( _ ad : AdropInterstitialAd) {
print ( "전면 광고 클릭" )
}
// 전면 광고가 표시되기 직전 (선택)
func onAdWillPresentFullScreen ( _ ad : AdropInterstitialAd) {
print ( "전면 광고 표시 직전" )
}
// 전면 광고가 표시된 직후 (선택)
func onAdDidPresentFullScreen ( _ ad : AdropInterstitialAd) {
print ( "전면 광고 표시 완료" )
}
// 전면 광고가 닫히기 직전 (선택)
func onAdWillDismissFullScreen ( _ ad : AdropInterstitialAd) {
print ( "전면 광고 닫히기 직전" )
}
// 전면 광고가 닫힌 직후 (선택)
func onAdDidDismissFullScreen ( _ ad : AdropInterstitialAd) {
print ( "전면 광고 닫힘" )
// 다음 광고를 미리 로드
loadInterstitialAd ()
}
// 전면 광고 표시 실패 (선택)
func onAdFailedToShowFullScreen ( _ ad : AdropInterstitialAd, _ errorCode : AdropErrorCode) {
print ( "전면 광고 표시 실패: \( errorCode ) " )
}
}
SwiftUI 구현
SwiftUI에서는 UIViewControllerRepresentable을 사용하거나, UIWindow에서 rootViewController를 가져와 표시할 수 있습니다.
방법 1: ViewModel 패턴
import SwiftUI
import AdropAds
// ViewModel
class InterstitialAdViewModel : ObservableObject {
@Published var isAdReady = false
@Published var isAdShowing = false
private var interstitialAd: AdropInterstitialAd ?
init () {
loadAd ()
}
func loadAd () {
interstitialAd = AdropInterstitialAd ( unitId : "YOUR_UNIT_ID" )
interstitialAd ? . delegate = self
interstitialAd ? . load ()
}
func showAd () {
guard let interstitialAd = interstitialAd,
let windowScene = UIApplication.shared.connectedScenes. first as? UIWindowScene,
let rootViewController = windowScene.windows. first ? .rootViewController else {
return
}
interstitialAd. show ( fromRootViewController : rootViewController)
}
}
// Delegate
extension InterstitialAdViewModel : AdropInterstitialAdDelegate {
func onAdReceived ( _ ad : AdropInterstitialAd) {
DispatchQueue. main . async {
self . isAdReady = true
}
}
func onAdFailedToReceive ( _ ad : AdropInterstitialAd, _ errorCode : AdropErrorCode) {
print ( "광고 수신 실패: \( errorCode ) " )
}
func onAdDidPresentFullScreen ( _ ad : AdropInterstitialAd) {
DispatchQueue. main . async {
self . isAdShowing = true
}
}
func onAdDidDismissFullScreen ( _ ad : AdropInterstitialAd) {
DispatchQueue. main . async {
self . isAdShowing = false
self . isAdReady = false
}
// 다음 광고 미리 로드
loadAd ()
}
}
// View
struct ContentView : View {
@StateObject private var adViewModel = InterstitialAdViewModel ()
var body: some View {
VStack {
Text ( "전면 광고 예제" )
. font (. title )
Button ( "전면 광고 표시" ) {
adViewModel. showAd ()
}
. disabled ( ! adViewModel. isAdReady )
. padding ()
}
}
}
방법 2: Helper를 이용한 간단한 구현
import SwiftUI
import AdropAds
// Helper
class InterstitialAdHelper : NSObject , ObservableObject , AdropInterstitialAdDelegate {
@Published var isAdReady = false
private var interstitialAd: AdropInterstitialAd ?
func loadAd ( unitId : String ) {
interstitialAd = AdropInterstitialAd ( unitId : unitId)
interstitialAd ? . delegate = self
interstitialAd ? . load ()
}
func showAd () {
guard let windowScene = UIApplication.shared.connectedScenes. first as? UIWindowScene,
let rootViewController = windowScene.windows. first ? .rootViewController else {
return
}
interstitialAd ? . show ( fromRootViewController : rootViewController)
}
func onAdReceived ( _ ad : AdropInterstitialAd) {
DispatchQueue. main . async {
self . isAdReady = true
}
}
func onAdFailedToReceive ( _ ad : AdropInterstitialAd, _ errorCode : AdropErrorCode) {
print ( "광고 수신 실패: \( errorCode ) " )
}
func onAdDidDismissFullScreen ( _ ad : AdropInterstitialAd) {
DispatchQueue. main . async {
self . isAdReady = false
}
}
}
// View
struct GameView : View {
@StateObject private var interstitialHelper = InterstitialAdHelper ()
@State private var level = 1
var body: some View {
VStack ( spacing : 20 ) {
Text ( "레벨 \( level ) " )
. font (. largeTitle )
Button ( "다음 레벨" ) {
if interstitialHelper.isAdReady {
interstitialHelper. showAd ()
}
level += 1
}
. padding ()
}
. onAppear {
interstitialHelper. loadAd ( unitId : "YOUR_UNIT_ID" )
}
}
}
델리게이트 메서드
필수 메서드
onAdReceived
(AdropInterstitialAd) -> Void
광고 수신 성공 시 호출됩니다. 이 시점에서 show()를 호출하여 광고를 표시할 수 있습니다.
onAdFailedToReceive
(AdropInterstitialAd, AdropErrorCode) -> Void
광고 수신 실패 시 호출됩니다. 에러 코드를 통해 실패 원인을 확인할 수 있습니다.
선택 메서드
onAdImpression
(AdropInterstitialAd) -> Void
광고 노출이 기록되었을 때 호출됩니다.
onAdClicked
(AdropInterstitialAd) -> Void
사용자가 광고를 클릭했을 때 호출됩니다.
onAdWillPresentFullScreen
(AdropInterstitialAd) -> Void
전면 광고가 표시되기 직전에 호출됩니다. 애니메이션 일시정지 등의 작업을 수행할 수 있습니다.
onAdDidPresentFullScreen
(AdropInterstitialAd) -> Void
전면 광고가 화면에 표시된 직후 호출됩니다.
onAdWillDismissFullScreen
(AdropInterstitialAd) -> Void
전면 광고가 닫히기 직전에 호출됩니다.
onAdDidDismissFullScreen
(AdropInterstitialAd) -> Void
전면 광고가 닫힌 직후 호출됩니다. 다음 광고를 미리 로드하기 좋은 시점입니다.
onAdFailedToShowFullScreen
(AdropInterstitialAd, AdropErrorCode) -> Void
광고 표시 실패 시 호출됩니다. 에러 코드를 통해 실패 원인을 확인할 수 있습니다.
생명주기
전면 광고는 다음과 같은 생명주기를 가집니다:
베스트 프랙티스
1. 광고 미리 로드
광고를 표시하기 전에 미리 로드하여 사용자 경험을 개선하세요.
class GameViewController : UIViewController {
private var interstitialAd: AdropInterstitialAd ?
private var isAdReady = false
override func viewDidLoad () {
super . viewDidLoad ()
// 화면 진입 시 미리 로드
preloadInterstitialAd ()
}
private func preloadInterstitialAd () {
interstitialAd = AdropInterstitialAd ( unitId : "YOUR_UNIT_ID" )
interstitialAd ? . delegate = self
interstitialAd ? . load ()
}
func onGameLevelComplete () {
// 레벨 완료 시 즉시 표시
if isAdReady {
interstitialAd ? . show ( fromRootViewController : self )
}
}
}
extension GameViewController : AdropInterstitialAdDelegate {
func onAdReceived ( _ ad : AdropInterstitialAd) {
isAdReady = true
}
func onAdDidDismissFullScreen ( _ ad : AdropInterstitialAd) {
isAdReady = false
// 다음 광고 미리 로드
preloadInterstitialAd ()
}
}
2. 적절한 표시 시점
앱의 자연스러운 전환 시점에 광고를 표시하세요.
// ✅ 좋은 예: 게임 레벨 전환
func onLevelComplete () {
saveProgress ()
showInterstitialAd ()
loadNextLevel ()
}
// ✅ 좋은 예: 콘텐츠 읽기 완료
func onArticleFinished () {
showInterstitialAd ()
}
// ❌ 나쁜 예: 사용자 액션 중간
func onButtonTap () {
showInterstitialAd () // 사용자 경험 저해
performAction ()
}
3. 닫기 후 재로드
광고가 닫힌 후 다음 광고를 미리 로드하세요.
func onAdDidDismissFullScreen ( _ ad : AdropInterstitialAd) {
// 즉시 다음 광고 로드
loadInterstitialAd ()
}
4. 에러 처리
광고 로드 실패에 대비한 처리를 구현하세요.
func onAdFailedToReceive ( _ ad : AdropInterstitialAd, _ errorCode : AdropErrorCode) {
switch errorCode {
case . networkError :
print ( "네트워크 오류: 나중에 다시 시도" )
retryAfterDelay ()
case . noFill :
print ( "표시할 광고 없음" )
continueWithoutAd ()
default :
print ( "광고 로드 실패: \( errorCode ) " )
}
}
private func retryAfterDelay () {
DispatchQueue. main . asyncAfter ( deadline : . now () + 30 ) {
self . loadInterstitialAd ()
}
}
5. 빈도 제한
너무 자주 광고를 표시하지 않도록 제한하세요.
class AdFrequencyManager {
private var lastAdShownTime: Date ?
private let minimumInterval: TimeInterval = 180 // 3분
func canShowAd () -> Bool {
guard let lastTime = lastAdShownTime else {
return true
}
return Date (). timeIntervalSince (lastTime) >= minimumInterval
}
func recordAdShown () {
lastAdShownTime = Date ()
}
}
// 사용 예시
let frequencyManager = AdFrequencyManager ()
func showInterstitialIfAllowed () {
guard frequencyManager. canShowAd () else {
print ( "광고 표시 간격이 너무 짧음" )
return
}
interstitialAd ? . show ( fromRootViewController : self )
}
func onAdDidPresentFullScreen ( _ ad : AdropInterstitialAd) {
frequencyManager. recordAdShown ()
}
테스트
테스트 유닛 ID 사용
개발 중에는 테스트 유닛 ID를 사용하세요.
# if DEBUG
let unitId = "PUBLIC_TEST_UNIT_ID_INTERSTITIAL"
# else
let unitId = "YOUR_PRODUCTION_UNIT_ID"
# endif
interstitialAd = AdropInterstitialAd ( unitId : unitId)
광고 로드 확인
광고가 정상적으로 로드되는지 확인하세요.
func onAdReceived ( _ ad : AdropInterstitialAd) {
print ( "✅ 전면 광고 로드 성공" )
assert (interstitialAd != nil , "광고 인스턴스가 nil입니다" )
}
func onAdFailedToReceive ( _ ad : AdropInterstitialAd, _ errorCode : AdropErrorCode) {
print ( "❌ 전면 광고 로드 실패: \( errorCode ) " )
// 개발 환경에서는 경고 표시
# if DEBUG
showDebugAlert ( "광고 로드 실패: \( errorCode ) " )
# endif
}
문제 해결
광고가 표시되지 않음
SDK가 초기화되었는지 확인
유닛 ID가 올바른지 확인
네트워크 연결 상태 확인
production 모드 설정 확인 (배포 시 true)
에러 코드를 확인하여 원인 파악
테스트 환경에서는 production: false 설정
광고 인벤토리 부족 시 나중에 재시도
show() 호출 후 아무 일도 일어나지 않음
onAdReceived 콜백 이후에 show()를 호출했는지 확인
rootViewController가 유효한지 확인
다른 뷰 컨트롤러가 이미 present되어 있지 않은지 확인
SwiftUI에서 rootViewController를 찾을 수 없음
// 안전하게 rootViewController 가져오기
func getRootViewController () -> UIViewController ? {
guard let windowScene = UIApplication.shared.connectedScenes. first as? UIWindowScene,
let rootViewController = windowScene.windows. first ? .rootViewController else {
print ( "rootViewController를 찾을 수 없습니다" )
return nil
}
// 최상위 presented view controller 찾기
var topController = rootViewController
while let presented = topController.presentedViewController {
topController = presented
}
return topController
}
// 사용
if let rootVC = getRootViewController () {
interstitialAd ? . show ( fromRootViewController : rootVC)
}
다음 단계