메인 콘텐츠로 건너뛰기

개요

스플래시 광고(Splash Ad)는 앱 실행 시 스플래시 화면에 표시되는 광고입니다. 앱의 로고와 함께 광고가 표시되어 자연스러운 사용자 경험을 제공합니다.

특징

  • 앱 시작 시 자연스러운 광고 노출
  • 앱 로고와 함께 브랜드 이미지 유지
  • 360px × 270px 고정 크기
  • 이미지 및 동영상 광고 지원
개발 환경에서는 테스트 유닛 ID를 사용하세요: PUBLIC_TEST_UNIT_ID_SPLASH

광고 크기

스플래시 광고는 고정된 크기를 사용합니다:
  • 크기: 360px × 270px (가로 × 세로)
  • 광고는 화면 하단에 표시되며, 상단에는 앱 로고가 배치됩니다

구현 방법

스플래시 광고는 앱의 요구사항에 따라 세 가지 방법으로 구현할 수 있습니다:
  1. AdropSplashAdViewController 사용 - 가장 간단한 방법
  2. AdropSplashAdView 사용 - 커스텀 스플래시 화면 구성
  3. SwiftUI 구현 - SwiftUI 앱에서 사용

방법 1: AdropSplashAdViewController 사용

가장 간단한 구현 방법입니다. AdropSplashAdViewController가 스플래시 화면을 자동으로 관리합니다.

UIKit 구현

import AdropAds

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        // Adrop SDK 초기화
        Adrop.initialize(production: false)

        return true
    }
}

SceneDelegate에서 스플래시 광고 표시

import UIKit
import AdropAds

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

    func scene(
        _ scene: UIScene,
        willConnectTo session: UISceneSession,
        options connectionOptions: UIScene.ConnectionOptions
    ) {
        guard let windowScene = (scene as? UIWindowScene) else { return }

        // Window 설정
        window = UIWindow(windowScene: windowScene)

        // 스플래시 광고 뷰 컨트롤러 생성
        let splashViewController = AdropSplashAdViewController(
            unitId: "YOUR_SPLASH_UNIT_ID",
            logoImage: UIImage(named: "app_logo")  // 앱 로고 이미지
        )
        splashViewController.delegate = self

        // 표시 시간 설정 (선택, 기본값 5초)
        splashViewController.displayDuration = 3.0

        // 스플래시 화면을 루트로 설정
        window?.rootViewController = splashViewController
        window?.makeKeyAndVisible()
    }
}

초기화 파라미터

파라미터타입설명
unitIdString애드컨트롤 콘솔에서 생성한 유닛 ID
logoImageUIImage?앱 로고 이미지. nil인 경우 로고 없이 표시
displayDurationTimeInterval광고 표시 시간 (초). 기본값 5.0

델리게이트 구현

// MARK: - AdropSplashAdDelegate
extension SceneDelegate: AdropSplashAdDelegate {
    // 스플래시 광고 종료 (필수)
    func onAdClose(impressed: Bool) {
        print("스플래시 광고 종료 - 노출됨: \(impressed)")

        // 메인 화면으로 전환
        let mainViewController = MainViewController()
        window?.rootViewController = mainViewController
    }

    // 광고 수신 성공 (선택)
    func onAdReceived(_ ad: AdropSplashAd) {
        print("스플래시 광고 수신 성공")
    }

    // 광고 수신 실패 (선택)
    func onAdFailedToReceive(_ ad: AdropSplashAd, _ errorCode: AdropErrorCode) {
        print("스플래시 광고 수신 실패: \(errorCode)")
        // 광고 실패 시에도 메인 화면으로 전환됩니다
    }

    // 광고 노출 (선택)
    func onAdImpression(_ ad: AdropSplashAd) {
        print("스플래시 광고 노출")
    }
}
AdropSplashAdViewController는 광고 로드, 표시, 타이머 관리를 자동으로 처리합니다. 광고가 로드되지 않더라도 자동으로 onAdClose가 호출되어 메인 화면으로 전환됩니다.

LaunchScreen과 연동

스플래시 광고를 표시하기 전에 시스템 LaunchScreen이 먼저 표시됩니다. 자연스러운 사용자 경험을 위해 LaunchScreen과 스플래시 광고 화면의 스타일을 일치시키는 것이 좋습니다.

LaunchScreen.storyboard 설정

  1. LaunchScreen.storyboard 파일을 열고 배경색을 스플래시 광고 화면과 동일하게 설정
  2. 앱 로고를 중앙에 배치 (스플래시 광고의 로고 위치와 일치)
  3. Info.plist에서 UILaunchStoryboardNameLaunchScreen으로 설정되어 있는지 확인
Info.plist
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
LaunchScreen과 스플래시 광고 화면의 배경색과 로고 위치가 일치하면 앱 시작 시 자연스러운 전환이 가능합니다.

방법 2: AdropSplashAdView 사용

커스텀 스플래시 화면을 직접 구성하고 싶을 때 사용합니다.
import UIKit
import AdropAds

class CustomSplashViewController: UIViewController {
    private var splashAd: AdropSplashAd?
    private let splashAdView = AdropSplashAdView()
    private let logoImageView = UIImageView()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        loadSplashAd()
    }

    private func setupUI() {
        view.backgroundColor = .white

        // 앱 로고 설정
        logoImageView.image = UIImage(named: "app_logo")
        logoImageView.contentMode = .scaleAspectFit
        logoImageView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(logoImageView)

        // 스플래시 광고 뷰 설정
        splashAdView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(splashAdView)

        NSLayoutConstraint.activate([
            // 로고: 화면 중앙 상단
            logoImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            logoImageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 100),
            logoImageView.widthAnchor.constraint(equalToConstant: 200),
            logoImageView.heightAnchor.constraint(equalToConstant: 200),

            // 광고: 화면 하단
            splashAdView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            splashAdView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            splashAdView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
            splashAdView.heightAnchor.constraint(equalToConstant: 270)  // 고정 높이
        ])
    }

    private func loadSplashAd() {
        splashAd = AdropSplashAd(unitId: "YOUR_SPLASH_UNIT_ID")
        splashAd?.delegate = self

        // 광고 뷰 설정
        splashAdView.delegate = self

        // 광고 로드 및 표시
        splashAd?.load(splashAdView)
    }
}

// MARK: - AdropSplashAdDelegate
extension CustomSplashViewController: AdropSplashAdDelegate {
    func onAdReceived(_ ad: AdropSplashAd) {
        print("스플래시 광고 수신 성공")
    }

    func onAdFailedToReceive(_ ad: AdropSplashAd, _ errorCode: AdropErrorCode) {
        print("스플래시 광고 수신 실패: \(errorCode)")
        // 실패 시 바로 메인 화면으로 전환
        transitionToMainScreen(impressed: false)
    }

    func onAdImpression(_ ad: AdropSplashAd) {
        print("스플래시 광고 노출")
    }
}

// MARK: - AdropSplashAdViewDelegate
extension CustomSplashViewController: AdropSplashAdViewDelegate {
    // 스플래시 광고 종료 (필수)
    func onAdClose(impressed: Bool) {
        print("스플래시 광고 종료 - 노출됨: \(impressed)")
        transitionToMainScreen(impressed: impressed)
    }

    // 광고 수신 성공 (선택)
    func onAdReceived(_ ad: AdropSplashAd) {
        print("스플래시 광고 뷰 수신 성공")
    }

    // 광고 수신 실패 (선택)
    func onAdFailedToReceive(_ ad: AdropSplashAd, _ errorCode: AdropErrorCode) {
        print("스플래시 광고 뷰 수신 실패: \(errorCode)")
    }

    // 광고 노출 (선택)
    func onAdImpression(_ ad: AdropSplashAd) {
        print("스플래시 광고 뷰 노출")
    }
}

// MARK: - Navigation
extension CustomSplashViewController {
    private func transitionToMainScreen(impressed: Bool) {
        guard let window = view.window else { return }

        let mainViewController = MainViewController()
        window.rootViewController = mainViewController

        // 부드러운 전환 애니메이션
        UIView.transition(
            with: window,
            duration: 0.3,
            options: .transitionCrossDissolve,
            animations: nil,
            completion: nil
        )
    }
}
AdropSplashAdView를 사용할 때는 AdropSplashAdViewDelegate를 구현해야 합니다. onAdClose(impressed:) 메서드는 필수로 구현해야 합니다.

방법 3: SwiftUI 구현

SwiftUI 앱에서 스플래시 광고를 구현하는 방법입니다.

SwiftUI Wrapper

import SwiftUI
import AdropAds

struct SplashAdView: UIViewControllerRepresentable {
    let unitId: String
    let logoImage: UIImage?
    @Binding var isPresented: Bool

    func makeUIViewController(context: Context) -> AdropSplashAdViewController {
        let controller = AdropSplashAdViewController(
            unitId: unitId,
            logoImage: logoImage
        )
        controller.delegate = context.coordinator
        return controller
    }

    func updateUIViewController(_ uiViewController: AdropSplashAdViewController, context: Context) {
        // 업데이트 불필요
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(isPresented: $isPresented)
    }

    class Coordinator: NSObject, AdropSplashAdDelegate {
        @Binding var isPresented: Bool

        init(isPresented: Binding<Bool>) {
            _isPresented = isPresented
        }

        func onAdClose(impressed: Bool) {
            print("스플래시 광고 종료 - 노출됨: \(impressed)")
            DispatchQueue.main.async {
                self.isPresented = false
            }
        }

        func onAdReceived(_ ad: AdropSplashAd) {
            print("스플래시 광고 수신 성공")
        }

        func onAdFailedToReceive(_ ad: AdropSplashAd, _ errorCode: AdropErrorCode) {
            print("스플래시 광고 수신 실패: \(errorCode)")
        }

        func onAdImpression(_ ad: AdropSplashAd) {
            print("스플래시 광고 노출")
        }
    }
}

SwiftUI App에서 사용

import SwiftUI
import AdropAds

@main
struct MyApp: App {
    init() {
        // SDK 초기화
        Adrop.initialize(production: false)
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    @State private var showSplash = true

    var body: some View {
        ZStack {
            if showSplash {
                SplashAdView(
                    unitId: "YOUR_SPLASH_UNIT_ID",
                    logoImage: UIImage(named: "app_logo"),
                    isPresented: $showSplash
                )
                .ignoresSafeArea()
            } else {
                MainView()
            }
        }
    }
}

struct MainView: View {
    var body: some View {
        NavigationView {
            VStack {
                Text("메인 화면")
                    .font(.largeTitle)
            }
            .navigationTitle("홈")
        }
    }
}

델리게이트 메서드

AdropSplashAdDelegate

AdropSplashAd를 사용할 때의 델리게이트입니다.
메서드필수설명
onAdClose(impressed:)선택스플래시 광고 종료 시 호출. impressed 파라미터로 광고 노출 여부 확인
onAdReceived(_:)선택광고 수신 성공 시 호출
onAdFailedToReceive(_:_:)선택광고 수신 실패 시 호출
onAdImpression(_:)선택광고 노출이 기록되었을 때 호출

AdropSplashAdViewDelegate

AdropSplashAdView를 사용할 때의 델리게이트입니다.
메서드필수설명
onAdClose(impressed:)필수스플래시 광고 종료 시 호출. 메인 화면 전환 처리 필요
onAdReceived(_:)선택광고 수신 성공 시 호출
onAdFailedToReceive(_:_:)선택광고 수신 실패 시 호출
onAdImpression(_:)선택광고 노출이 기록되었을 때 호출

impressed 파라미터

onAdClose(impressed:) 메서드의 impressed 파라미터는 광고가 실제로 노출되었는지 여부를 나타냅니다.
func onAdClose(impressed: Bool) {
    if impressed {
        print("광고가 사용자에게 노출되었습니다")
        // 광고 노출 후 처리 로직
    } else {
        print("광고가 노출되지 않았습니다 (로드 실패 또는 스킵)")
        // 광고 미노출 처리 로직
    }

    // 메인 화면으로 전환
    transitionToMainScreen()
}

impressed가 false인 경우

  • 광고 로드 실패
  • 네트워크 오류
  • 사용자가 광고를 보기 전에 스킵
  • 광고 인벤토리 부족

베스트 프랙티스

1. 적절한 타이머 설정

스플래시 광고는 너무 짧거나 길지 않게 표시해야 합니다.
// AdropSplashAdViewController는 자동으로 타이머를 관리합니다
// 기본값: 5초 (광고 로드 시간 포함)

2. 로고 이미지 최적화

앱 로고는 적절한 크기로 준비하여 로딩 시간을 최소화하세요.
// 권장 로고 크기: 200x200 ~ 300x300 포인트
let logoImage = UIImage(named: "app_logo")  // @2x, @3x 버전 준비

3. 실패 처리

광고 로드 실패 시에도 앱이 정상적으로 시작되도록 처리하세요.
func onAdFailedToReceive(_ ad: AdropSplashAd, _ errorCode: AdropErrorCode) {
    print("광고 로드 실패: \(errorCode)")
    // 실패해도 메인 화면으로 전환
    // AdropSplashAdViewController는 자동으로 처리
}

4. 부드러운 화면 전환

메인 화면으로 전환 시 자연스러운 애니메이션을 사용하세요.
private func transitionToMainScreen() {
    guard let window = view.window else { return }

    let mainViewController = MainViewController()

    UIView.transition(
        with: window,
        duration: 0.3,
        options: .transitionCrossDissolve,
        animations: {
            window.rootViewController = mainViewController
        },
        completion: nil
    )
}

5. 테스트 환경 구분

개발과 배포 환경을 구분하여 테스트하세요.
#if DEBUG
let splashUnitId = "PUBLIC_TEST_UNIT_ID_SPLASH"
let isProduction = false
#else
let splashUnitId = "YOUR_PRODUCTION_SPLASH_UNIT_ID"
let isProduction = true
#endif

// SDK 초기화
Adrop.initialize(production: isProduction)

// 스플래시 광고 생성
let splashViewController = AdropSplashAdViewController(
    unitId: splashUnitId,
    logoImage: UIImage(named: "app_logo")
)

완전한 SceneDelegate 예제

import UIKit
import AdropAds

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

    func scene(
        _ scene: UIScene,
        willConnectTo session: UISceneSession,
        options connectionOptions: UIScene.ConnectionOptions
    ) {
        guard let windowScene = (scene as? UIWindowScene) else { return }

        // Window 설정
        window = UIWindow(windowScene: windowScene)

        #if DEBUG
        let splashUnitId = "PUBLIC_TEST_UNIT_ID_SPLASH"
        #else
        let splashUnitId = "YOUR_PRODUCTION_SPLASH_UNIT_ID"
        #endif

        // 스플래시 광고 뷰 컨트롤러 생성
        let splashViewController = AdropSplashAdViewController(
            unitId: splashUnitId,
            logoImage: UIImage(named: "app_logo")
        )
        splashViewController.delegate = self

        // 루트 뷰 컨트롤러 설정
        window?.rootViewController = splashViewController
        window?.makeKeyAndVisible()
    }
}

// MARK: - AdropSplashAdDelegate
extension SceneDelegate: AdropSplashAdDelegate {
    func onAdClose(impressed: Bool) {
        print("스플래시 광고 종료 - 노출됨: \(impressed)")

        // 메인 화면으로 전환
        let mainViewController = MainViewController()
        let navigationController = UINavigationController(rootViewController: mainViewController)

        guard let window = window else { return }

        UIView.transition(
            with: window,
            duration: 0.3,
            options: .transitionCrossDissolve,
            animations: {
                window.rootViewController = navigationController
            },
            completion: nil
        )
    }

    func onAdReceived(_ ad: AdropSplashAd) {
        print("✅ 스플래시 광고 수신 성공")
    }

    func onAdFailedToReceive(_ ad: AdropSplashAd, _ errorCode: AdropErrorCode) {
        print("❌ 스플래시 광고 수신 실패: \(errorCode)")
        // AdropSplashAdViewController가 자동으로 onAdClose를 호출합니다
    }

    func onAdImpression(_ ad: AdropSplashAd) {
        print("📊 스플래시 광고 노출 기록")
    }
}

테스트

테스트 유닛 ID

개발 중에는 테스트 유닛 ID를 사용하세요.
// 테스트 유닛 ID
let testUnitId = "PUBLIC_TEST_UNIT_ID_SPLASH"

// 또는 AdropUnitId 사용
let testUnitId = AdropUnitId.PUBLIC_TEST_UNIT_ID_SPLASH
실제 배포 시에는 반드시 애드컨트롤 콘솔에서 생성한 실제 유닛 ID를 사용하세요. 테스트 유닛 ID로 배포하면 광고 수익이 발생하지 않습니다.

디버깅

광고 이벤트를 로그로 확인하세요.
extension SceneDelegate: AdropSplashAdDelegate {
    func onAdReceived(_ ad: AdropSplashAd) {
        #if DEBUG
        print("✅ 스플래시 광고 수신")
        #endif
    }

    func onAdFailedToReceive(_ ad: AdropSplashAd, _ errorCode: AdropErrorCode) {
        #if DEBUG
        print("❌ 스플래시 광고 실패: \(errorCode)")
        print("  - 네트워크 상태 확인")
        print("  - 유닛 ID 확인: \(ad.unitId)")
        #endif
    }

    func onAdImpression(_ ad: AdropSplashAd) {
        #if DEBUG
        print("📊 스플래시 광고 노출")
        #endif
    }

    func onAdClose(impressed: Bool) {
        #if DEBUG
        print("🚪 스플래시 광고 종료")
        print("  - 노출 여부: \(impressed)")
        #endif
    }
}

문제 해결

  • window.rootViewController가 올바르게 설정되었는지 확인
  • SceneDelegate가 활성화되어 있는지 확인 (Info.plist)
  • SDK 초기화가 완료되었는지 확인
  • 네트워크 연결 상태 확인
  • 유닛 ID가 올바른지 확인
  • 테스트 환경에서는 production: false 설정 확인
  • onAdFailedToReceive 에러 코드 확인
  • onAdClose(impressed:) 델리게이트가 구현되었는지 확인
  • 화면 전환 코드가 메인 스레드에서 실행되는지 확인
func onAdClose(impressed: Bool) {
    DispatchQueue.main.async {
        // 화면 전환 코드
    }
}
  • AdropSplashAdViewDelegate를 구현했는지 확인
  • splashAdView.delegate = self 설정 확인
  • onAdClose(impressed:) 메서드가 필수로 구현되어야 함

다음 단계