메인 콘텐츠로 건너뛰기

개요

팝업 광고(Popup Ad)는 특정 순간에 화면에 나타나는 광고 포맷입니다. 앱 실행 시, 콘텐츠 로드 완료 시, 특정 이벤트 발생 시 등 원하는 타이밍에 표시할 수 있으며, 사용자가 닫기 버튼을 누르거나 “오늘 하루 보지 않기”를 선택하여 종료할 수 있습니다.

특징

  • 화면 중앙 또는 하단에 표시되는 팝업 형태
  • 이미지 및 동영상 광고 지원
  • 닫기, 딤(배경) 클릭, “오늘 하루 보지 않기” 옵션 제공
  • 배경색, 텍스트 색상 등 커스터마이징 가능
  • 사용자 경험을 해치지 않으면서도 효과적인 광고 경험
개발 환경에서는 테스트 유닛 ID를 사용하세요. 테스트 유닛 ID 섹션을 참고하세요.

구현 단계

팝업 광고는 다음 4단계로 구현합니다:
  1. 초기화 - AdropPopupAd 인스턴스 생성
  2. Delegate 설정 - 광고 및 닫기 이벤트 수신을 위한 Delegate 설정
  3. 광고 로드 - 광고 요청 및 수신
  4. 광고 표시 - 화면에 광고 표시

UIKit 구현

기본 구현

import AdropAds

class ViewController: UIViewController {
    private var popupAd: AdropPopupAd?

    override func viewDidLoad() {
        super.viewDidLoad()
        loadPopupAd()
    }

    // 1. 광고 초기화 및 로드
    private func loadPopupAd() {
        popupAd = AdropPopupAd(unitId: "YOUR_POPUP_UNIT_ID")
        popupAd?.delegate = self
        popupAd?.closeDelegate = self
        popupAd?.load()
    }

    // 2. 광고 표시
    private func showPopupAd() {
        guard let popupAd = popupAd,
              popupAd.isLoaded else { return }
        popupAd.show(fromRootViewController: self)
    }
}

Delegate 구현

// 광고 Delegate 구현
extension ViewController: AdropPopupAdDelegate {
    // 광고 수신 성공 (필수)
    func onAdReceived(_ ad: AdropPopupAd) {
        print("팝업 광고 수신 완료")
        // 광고가 준비되면 표시
        showPopupAd()
    }

    // 광고 수신 실패 (필수)
    func onAdFailedToReceive(_ ad: AdropPopupAd, _ errorCode: AdropErrorCode) {
        print("팝업 광고 수신 실패: \(errorCode)")
    }

    // 광고 노출 (선택)
    func onAdImpression(_ ad: AdropPopupAd) {
        print("팝업 광고 노출")
    }

    // 광고 클릭 (선택)
    func onAdClicked(_ ad: AdropPopupAd) {
        print("팝업 광고 클릭")
    }

    // 팝업 광고가 표시되기 직전 (선택)
    func onAdWillPresentFullScreen(_ ad: AdropPopupAd) {
        print("팝업 광고 표시 직전")
    }

    // 팝업 광고가 표시된 직후 (선택)
    func onAdDidPresentFullScreen(_ ad: AdropPopupAd) {
        print("팝업 광고 표시 완료")
    }

    // 팝업 광고가 닫히기 직전 (선택)
    func onAdWillDismissFullScreen(_ ad: AdropPopupAd) {
        print("팝업 광고 닫히기 직전")
    }

    // 팝업 광고가 닫힌 직후 (선택)
    func onAdDidDismissFullScreen(_ ad: AdropPopupAd) {
        print("팝업 광고 닫힘")
        // 다음 광고를 미리 로드
        loadPopupAd()
    }

    // 팝업 광고 표시 실패 (선택)
    func onAdFailedToShowFullScreen(_ ad: AdropPopupAd, _ errorCode: AdropErrorCode) {
        print("팝업 광고 표시 실패: \(errorCode)")
    }
}

// 닫기 Delegate 구현
extension ViewController: AdropPopupAdCloseDelegate {
    // 닫기 버튼 클릭 (선택)
    func onClosed(_ ad: AdropPopupAd) {
        print("팝업 광고 닫기 버튼 클릭")
    }

    // 딤(배경) 클릭 (선택)
    func onDimClicked(_ ad: AdropPopupAd) {
        print("팝업 광고 딤 영역 클릭")
    }

    // "오늘 하루 보지 않기" 클릭 (선택)
    func onTodayOffClicked(_ ad: AdropPopupAd) {
        print("오늘 하루 보지 않기 선택")
        // SDK가 자동으로 오늘 하루 숨김 처리를 합니다.
        // 이 콜백은 분석 로깅이나 커스텀 UI 업데이트에 활용하세요.
    }
}

SwiftUI 구현

SwiftUI에서는 UIViewControllerRepresentable을 사용하거나, UIWindow에서 rootViewController를 가져와 표시할 수 있습니다.

ViewModel 패턴

import SwiftUI
import AdropAds

// ViewModel
class PopupAdViewModel: ObservableObject {
    @Published var isAdReady = false
    @Published var isAdShowing = false

    private var popupAd: AdropPopupAd?

    init() {
        loadAd()
    }

    func loadAd() {
        popupAd = AdropPopupAd(unitId: "YOUR_POPUP_UNIT_ID")
        popupAd?.delegate = self
        popupAd?.closeDelegate = self
        popupAd?.load()
    }

    func showAd() {
        guard let popupAd = popupAd,
              let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
              let rootViewController = windowScene.windows.first?.rootViewController else {
            return
        }

        popupAd.show(fromRootViewController: rootViewController)
    }

}

// 광고 Delegate
extension PopupAdViewModel: AdropPopupAdDelegate {
    func onAdReceived(_ ad: AdropPopupAd) {
        DispatchQueue.main.async {
            self.isAdReady = true
        }
    }

    func onAdFailedToReceive(_ ad: AdropPopupAd, _ errorCode: AdropErrorCode) {
        print("광고 수신 실패: \(errorCode)")
    }

    func onAdDidPresentFullScreen(_ ad: AdropPopupAd) {
        DispatchQueue.main.async {
            self.isAdShowing = true
        }
    }

    func onAdDidDismissFullScreen(_ ad: AdropPopupAd) {
        DispatchQueue.main.async {
            self.isAdShowing = false
            self.isAdReady = false
        }
        // 다음 광고 미리 로드
        loadAd()
    }
}

// 닫기 Delegate
extension PopupAdViewModel: AdropPopupAdCloseDelegate {
    func onClosed(_ ad: AdropPopupAd) {
        print("팝업 광고 닫기")
    }

    func onDimClicked(_ ad: AdropPopupAd) {
        print("팝업 광고 딤 클릭")
    }

    func onTodayOffClicked(_ ad: AdropPopupAd) {
        print("오늘 하루 보지 않기 선택")
        // SDK가 자동으로 오늘 하루 숨김 처리를 합니다.
        // 이 콜백은 분석 로깅이나 커스텀 UI 업데이트에 활용하세요.
    }
}

// View
struct ContentView: View {
    @StateObject private var adViewModel = PopupAdViewModel()

    var body: some View {
        VStack {
            Text("팝업 광고 예제")
                .font(.title)

            Button("팝업 광고 표시") {
                adViewModel.showAd()
            }
            .disabled(!adViewModel.isAdReady)
            .padding()
        }
        .onAppear {
            // 앱 시작 시 자동 표시
            if adViewModel.isAdReady {
                adViewModel.showAd()
            }
        }
    }
}

커스터마이징

팝업 광고의 외형을 커스터마이징할 수 있습니다.

배경색 및 텍스트 색상 설정

private func loadPopupAd() {
    popupAd = AdropPopupAd(unitId: "YOUR_POPUP_UNIT_ID")
    popupAd?.delegate = self
    popupAd?.closeDelegate = self

    // 배경색 설정
    popupAd?.backgroundColor = UIColor.black.withAlphaComponent(0.8)

    // "오늘 하루 보지 않기" 텍스트 색상
    popupAd?.hideForTodayTextColor = UIColor.white

    // 닫기 버튼 텍스트 색상
    popupAd?.closeTextColor = UIColor.white

    // CTA 버튼 텍스트 색상
    popupAd?.ctaTextColor = UIColor.white

    popupAd?.load()
}

커스터마이징 옵션

속성타입설명기본값
backgroundColorUIColor?액션 바 배경색nil
hideForTodayTextColorUIColor?”오늘 하루 보지 않기” 텍스트 색상흰색
closeTextColorUIColor?닫기 버튼 텍스트 색상흰색
ctaTextColorUIColor?CTA(Call to Action) 버튼 텍스트 색상흰색

Delegate 메서드

AdropPopupAdDelegate (광고 이벤트)

필수 메서드

onAdReceived
(AdropPopupAd) -> Void
광고 수신 성공 시 호출됩니다. 이 시점에서 show()를 호출하여 광고를 표시할 수 있습니다.
onAdFailedToReceive
(AdropPopupAd, AdropErrorCode) -> Void
광고 수신 실패 시 호출됩니다. 에러 코드를 통해 실패 원인을 확인할 수 있습니다.

선택 메서드

onAdImpression
(AdropPopupAd) -> Void
광고 노출이 기록되었을 때 호출됩니다.
onAdClicked
(AdropPopupAd) -> Void
사용자가 광고를 클릭했을 때 호출됩니다.
onAdWillPresentFullScreen
(AdropPopupAd) -> Void
팝업 광고가 표시되기 직전에 호출됩니다.
onAdDidPresentFullScreen
(AdropPopupAd) -> Void
팝업 광고가 화면에 표시된 직후 호출됩니다.
onAdWillDismissFullScreen
(AdropPopupAd) -> Void
팝업 광고가 닫히기 직전에 호출됩니다.
onAdDidDismissFullScreen
(AdropPopupAd) -> Void
팝업 광고가 닫힌 직후 호출됩니다. 다음 광고를 미리 로드하기 좋은 시점입니다.
onAdFailedToShowFullScreen
(AdropPopupAd, AdropErrorCode) -> Void
광고 표시 실패 시 호출됩니다. 에러 코드를 통해 실패 원인을 확인할 수 있습니다.

AdropPopupAdCloseDelegate (닫기 이벤트)

모든 메서드가 선택사항입니다.
onClosed
(AdropPopupAd) -> Void
사용자가 닫기 버튼을 클릭했을 때 호출됩니다.
onDimClicked
(AdropPopupAd) -> Void
사용자가 팝업 외부(딤 영역)를 클릭했을 때 호출됩니다.
onTodayOffClicked
(AdropPopupAd) -> Void
사용자가 “오늘 하루 보지 않기”를 선택했을 때 호출됩니다. 이 콜백에서 날짜를 저장하여 하루 동안 광고를 표시하지 않도록 구현할 수 있습니다.

커스텀 클릭 처리

useCustomClick을 사용하여 광고 클릭 동작을 직접 제어할 수 있습니다. 활성화하면 SDK가 클릭 시 자동으로 URL을 열지 않으며, 직접 처리할 수 있습니다.

useCustomClick

popupAd = AdropPopupAd(unitId: "YOUR_POPUP_UNIT_ID")
popupAd?.useCustomClick = true
popupAd?.delegate = self
popupAd?.load()
useCustomClicktrue이면, SDK는 광고 클릭 시 자동으로 URL을 열지 않습니다. onAdClicked delegate 콜백은 계속 호출되며, open() 메서드를 사용하거나 직접 네비게이션을 처리할 수 있습니다.

open()

광고의 목적지 URL을 엽니다. 커스텀 URL을 전달할 수도 있습니다.
// 광고의 기본 목적지 URL 열기
popupAd?.open()

// 커스텀 URL 열기
popupAd?.open("https://example.com")

// 인앱 브라우저를 사용하여 열기
popupAd?.open(nil, useInAppBrowser: true)

close()

프로그래밍 방식으로 팝업 광고를 닫습니다.
popupAd?.close()

프로퍼티

프로퍼티타입설명
unitIdString광고 유닛 ID
isLoadedBool광고가 로드되었는지 여부
useCustomClickBool광고 클릭을 수동으로 처리할지 여부
destinationURLString?현재 표시 중인 광고의 목적지 URL
creativeIdString?현재 표시 중인 광고의 크리에이티브 ID
txIdString현재 표시 중인 광고의 트랜잭션 ID
txIds[String]로드된 모든 광고의 트랜잭션 ID
campaignIdString현재 표시 중인 광고의 캠페인 ID
campaignIds[String]로드된 모든 광고의 캠페인 ID
creativeIds[String]로드된 모든 광고의 크리에이티브 ID
browserTargetBrowserTarget?광고 클릭 시 URL 열기 방식

클로저 기반 콜백

Delegate 외에 클로저 기반 콜백도 사용할 수 있습니다. 전체 delegate 패턴을 구현하고 싶지 않을 때 편리합니다.
let popupAd = AdropPopupAd(unitId: "YOUR_POPUP_UNIT_ID")

// 광고 이벤트
popupAd.onAdReceived = { ad in
    print("광고 수신 완료")
}
popupAd.onAdFailedToReceive = { ad, errorCode in
    print("광고 수신 실패: \(errorCode)")
}
popupAd.onAdClicked = { ad in
    print("광고 클릭, 목적지: \(ad.destinationURL ?? "")")
}
popupAd.onAdImpression = { ad in
    print("광고 노출")
}
popupAd.onAdWillPresentFullScreen = { ad in
    print("표시 직전")
}
popupAd.onAdDidPresentFullScreen = { ad in
    print("표시 완료")
}
popupAd.onAdWillDismissFullScreen = { ad in
    print("닫히기 직전")
}
popupAd.onAdDidDismissFullScreen = { ad in
    print("닫힘")
}
popupAd.onAdFailedToShowFullScreen = { ad, errorCode in
    print("표시 실패: \(errorCode)")
}

// 닫기 이벤트
popupAd.onClosed = { ad in
    print("닫힘")
}
popupAd.onDimClicked = { ad in
    print("딤 클릭")
}
popupAd.onTodayOffClicked = { ad in
    print("오늘 하루 보지 않기")
}

popupAd.load()
Delegate 콜백과 클로저 기반 콜백은 동시에 사용할 수 있습니다. 둘 다 호출됩니다.

”오늘 하루 보지 않기” 구현

사용자가 “오늘 하루 보지 않기”를 선택했을 때 적절히 처리하는 방법입니다.
SDK가 “오늘 하루 보지 않기” 상태를 자동으로 관리합니다. 다음 예제는 기본 처리 외에 커스텀 동작을 추가하는 방법을 보여줍니다.

구현

SDK가 “오늘 하루 보지 않기”를 선택한 경우 load() 시 자동으로 로드를 건너뜁니다. 별도의 수동 체크 없이 load()만 호출하면 됩니다.
class PopupAdManager {
    private var popupAd: AdropPopupAd?

    // 광고 로드 및 표시
    func loadAndShowAd(from viewController: UIViewController) {
        popupAd = AdropPopupAd(unitId: "YOUR_POPUP_UNIT_ID")
        popupAd?.delegate = self
        popupAd?.closeDelegate = self
        popupAd?.load()
    }
}

extension PopupAdManager: AdropPopupAdDelegate {
    func onAdReceived(_ ad: AdropPopupAd) {
        // 광고 수신 후 자동 표시
        if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
           let rootViewController = windowScene.windows.first?.rootViewController {
            ad.show(fromRootViewController: rootViewController)
        }
    }

    func onAdFailedToReceive(_ ad: AdropPopupAd, _ errorCode: AdropErrorCode) {
        print("광고 수신 실패: \(errorCode)")
    }
}

extension PopupAdManager: AdropPopupAdCloseDelegate {
    func onTodayOffClicked(_ ad: AdropPopupAd) {
        print("오늘 하루 보지 않기 선택")
        // SDK가 자동으로 오늘 하루 숨김 처리를 합니다.
        // 이 콜백은 분석 로깅이나 커스텀 UI 업데이트에 활용하세요.
    }
}

모범 사례

1. 적절한 표시 시점

팝업 광고는 다음 시점에 표시하는 것이 효과적입니다:
// ✅ 좋은 예: 앱 시작 시
func applicationDidFinishLaunching() {
    loadAndShowPopupAd()
}

// ✅ 좋은 예: 콘텐츠 로드 완료 시
func onContentLoaded() {
    if shouldShowPopupAd() {
        showPopupAd()
    }
}

// ✅ 좋은 예: 특정 이벤트 완료 시
func onAchievementUnlocked() {
    showPopupAd()
}

// ❌ 나쁜 예: 사용자가 작업 중일 때
func onUserTyping() {
    showPopupAd() // 사용자 경험 저해
}

2. “오늘 하루 보지 않기” 존중

사용자가 “오늘 하루 보지 않기”를 선택했다면 반드시 준수하세요.
func shouldShowPopupAd() -> Bool {
    // 오늘 하루 보지 않기 확인
    guard canShowAdToday() else {
        return false
    }

    // 다른 조건 확인
    return true
}

3. 빈도 제한

팝업 광고를 너무 자주 표시하지 마세요.
class PopupAdFrequencyManager {
    private let lastShownKey = "popupAd_lastShown"
    private let minimumInterval: TimeInterval = 3600 // 1시간

    func canShowAd() -> Bool {
        // 오늘 하루 보지 않기 확인
        guard canShowAdToday() else {
            return false
        }

        // 최소 시간 간격 확인
        guard let lastShown = UserDefaults.standard.object(forKey: lastShownKey) as? Date else {
            return true
        }

        return Date().timeIntervalSince(lastShown) >= minimumInterval
    }

    func recordAdShown() {
        UserDefaults.standard.set(Date(), forKey: lastShownKey)
    }
}

테스트 유닛 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
실제 배포 시에는 반드시 애드컨트롤 콘솔에서 생성한 실제 유닛 ID를 사용하세요.

관련 문서

시작하기

SDK 설치 및 초기화

전면 광고

전면 광고 구현하기

보상형 광고

보상형 광고 구현하기

배너 광고

배너 광고 구현하기