팝업 광고(Popup Ad)는 특정 순간에 화면에 나타나는 광고 포맷입니다. 앱 실행 시, 콘텐츠 로드 완료 시, 특정 이벤트 발생 시 등 원하는 타이밍에 표시할 수 있으며, 사용자가 닫기 버튼을 누르거나 “오늘 하루 보지 않기”를 선택하여 종료할 수 있습니다.
- 화면 중앙 또는 하단에 표시되는 팝업 형태
- 이미지 및 동영상 광고 지원
- 닫기, 딤(배경) 클릭, “오늘 하루 보지 않기” 옵션 제공
- 배경색, 텍스트 색상 등 커스터마이징 가능
- 사용자 경험을 해치지 않으면서도 효과적인 광고 경험
개발 환경에서는 테스트 유닛 ID를 사용하세요. 테스트 유닛 ID 섹션을 참고하세요.
구현 단계
팝업 광고는 다음 4단계로 구현합니다:
- 초기화 - AdropPopupAd 인스턴스 생성
- Delegate 설정 - 광고 및 닫기 이벤트 수신을 위한 Delegate 설정
- 광고 로드 - 광고 요청 및 수신
- 광고 표시 - 화면에 광고 표시
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()
}
커스터마이징 옵션
| 속성 | 타입 | 설명 | 기본값 |
|---|
backgroundColor | UIColor? | 액션 바 배경색 | nil |
hideForTodayTextColor | UIColor? | ”오늘 하루 보지 않기” 텍스트 색상 | 흰색 |
closeTextColor | UIColor? | 닫기 버튼 텍스트 색상 | 흰색 |
ctaTextColor | UIColor? | CTA(Call to Action) 버튼 텍스트 색상 | 흰색 |
Delegate 메서드
필수 메서드
광고 수신 성공 시 호출됩니다. 이 시점에서 show()를 호출하여 광고를 표시할 수 있습니다.
onAdFailedToReceive
(AdropPopupAd, AdropErrorCode) -> Void
광고 수신 실패 시 호출됩니다. 에러 코드를 통해 실패 원인을 확인할 수 있습니다.
선택 메서드
onAdWillPresentFullScreen
팝업 광고가 표시되기 직전에 호출됩니다.
onAdWillDismissFullScreen
팝업 광고가 닫히기 직전에 호출됩니다.
팝업 광고가 닫힌 직후 호출됩니다. 다음 광고를 미리 로드하기 좋은 시점입니다.
onAdFailedToShowFullScreen
(AdropPopupAd, AdropErrorCode) -> Void
광고 표시 실패 시 호출됩니다. 에러 코드를 통해 실패 원인을 확인할 수 있습니다.
모든 메서드가 선택사항입니다.
사용자가 닫기 버튼을 클릭했을 때 호출됩니다.
사용자가 팝업 외부(딤 영역)를 클릭했을 때 호출됩니다.
사용자가 “오늘 하루 보지 않기”를 선택했을 때 호출됩니다. 이 콜백에서 날짜를 저장하여 하루 동안 광고를 표시하지 않도록 구현할 수 있습니다.
커스텀 클릭 처리
useCustomClick을 사용하여 광고 클릭 동작을 직접 제어할 수 있습니다. 활성화하면 SDK가 클릭 시 자동으로 URL을 열지 않으며, 직접 처리할 수 있습니다.
useCustomClick
popupAd = AdropPopupAd(unitId: "YOUR_POPUP_UNIT_ID")
popupAd?.useCustomClick = true
popupAd?.delegate = self
popupAd?.load()
useCustomClick이 true이면, SDK는 광고 클릭 시 자동으로 URL을 열지 않습니다. onAdClicked delegate 콜백은 계속 호출되며, open() 메서드를 사용하거나 직접 네비게이션을 처리할 수 있습니다.
open()
광고의 목적지 URL을 엽니다. 커스텀 URL을 전달할 수도 있습니다.
// 광고의 기본 목적지 URL 열기
popupAd?.open()
// 커스텀 URL 열기
popupAd?.open("https://example.com")
// 인앱 브라우저를 사용하여 열기
popupAd?.open(nil, useInAppBrowser: true)
close()
프로그래밍 방식으로 팝업 광고를 닫습니다.
프로퍼티
| 프로퍼티 | 타입 | 설명 |
|---|
unitId | String | 광고 유닛 ID |
isLoaded | Bool | 광고가 로드되었는지 여부 |
useCustomClick | Bool | 광고 클릭을 수동으로 처리할지 여부 |
destinationURL | String? | 현재 표시 중인 광고의 목적지 URL |
creativeId | String? | 현재 표시 중인 광고의 크리에이티브 ID |
txId | String | 현재 표시 중인 광고의 트랜잭션 ID |
txIds | [String] | 로드된 모든 광고의 트랜잭션 ID |
campaignId | String | 현재 표시 중인 광고의 캠페인 ID |
campaignIds | [String] | 로드된 모든 광고의 캠페인 ID |
creativeIds | [String] | 로드된 모든 광고의 크리에이티브 ID |
browserTarget | BrowserTarget? | 광고 클릭 시 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를 사용하세요.
관련 문서