Apps Kit SDK logoApps Kit SDK
개발자 문서 · iOS 연동

4. SDK 초기화

4.1 AppDelegate

AKSBaseAppDelegate를 상속하세요. 템플릿 메서드 패턴을 사용하는 이 기본 클래스는 Firebase 설정, AdMob 초기화, SDK 초기화, 원격 구성 초기 설정을 처리하며, 앱에서 필요한 동작을 연결할 수 있는 여러 open 훅을 제공합니다.

swift
import UIKit
import AppsKit
import AKSKit

class AppDelegate: AKSBaseAppDelegate {

    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        AppsKitSDKAdsManagerIOS.instance.initialize(userHasGivenConsent: true, isCCPAConsent: true)

        // super.application(...) does, in order:
        //   FirebaseApp.configure() -> MobileAds.shared.start() -> setupAdBridge()
        //   -> AppsKitSDK init/setDevMode/setTestMode/saveDefaultConfigJson
        //   -> configureSDK() -> manageRemoteConfigs(...)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }

    /// Called by the base class during the sequence above. Optional — only needed if your
    /// app has its own ad-loading abstraction layer that needs to be wired up to AKS. If you
    /// call `AppsKitSDKAdsManagerIOS.instance` directly from your own Swift code (§5), leave
    /// this empty.
    override func setupAdBridge() {}

    override func isDevMode() -> Bool { return false } // wire to your own debug flag
    override func isTestMode() -> Bool { return false }

    override func defaultConfigJson() -> String? {
        return "<encrypted-config-json-from-aks-portal>"
    }

    /// Called after dev/test mode flags are applied — use this for anything that needs
    /// to happen after the base setup but before remote config is ready (e.g. initializing
    /// AppLovin MAX directly).
    override func configureSDK() {}

    override func onConfigsReadyToUse() {
        // optional — fires once Firebase Remote Config has been fetched/activated
    }
}

AKSBaseAppDelegate에서 제공하는 open 훅의 전체 목록: setupAdBridge(), isDevMode() -> Bool (기본값 false), isTestMode() -> Bool (기본값 false), defaultConfigJson() -> String? (기본값 nil), timeToFetchRemoteConfigInSeconds() -> Int (기본값 3600), onConfigsReadyToUse(), configureSDK().

4.2 AKSBaseAppDelegate를 상속하지 않고 초기화하기

AKSBaseAppDelegate 상속은 필수가 아닙니다. 편의를 위한 래퍼일 뿐입니다. 앱에서 이미 자체 UIApplicationDelegate를 사용 중이고 이를 유지해야 한다면, AKSBaseAppDelegate가 내부적으로 호출하는 것과 동일한 AppsKitSDK/AKSKit 메서드를 앱의 application(_:didFinishLaunchingWithOptions:)에서 직접 호출하세요.

swift
import UIKit
import AppsKit   // for makeDefaultIOSAdHandler() — see below
import AKSKit
import FirebaseCore
import FirebaseRemoteConfig
import GoogleMobileAds

class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        FirebaseApp.configure()
        MobileAds.shared.start()

        // If your app has its own ad-loading abstraction layer to wire up to AKS, do it
        // around here — most apps don't need this; see §5 to call ad formats directly.

        let sdkInstance = AppsKitSDK.shared
        sdkInstance.setIOSAdHandler(iosAdHandler: makeDefaultIOSAdHandler())
        sdkInstance.initialize(
            context: PlatformContext(delegate: nil),
            application: PlatformApplication(application: UIApplication.shared)
        )

        sdkInstance.setDevMode(value: false) // wire to your own debug flag
        sdkInstance.setTestMode(value: false)
        sdkInstance.setTimeToFetchRemoteConfigInSeconds(intervalToFetchRemoteConfigInSeconds: 3600) // optional, defaults to 3600

        sdkInstance.saveDefaultConfigJson(encryptedJson: "<encrypted-config-json-from-aks-portal>")
        sdkInstance.manageRemoteConfigs(onRemoteConfigReady: RemoteConfigReadyBridge {
            // optional — your own hook into the fetched remote config
        })

        AdsManager.shared.setAppExitTime(appExitTime: 0)
        AKSUtils.shared.cleanCachedData()

        return true
    }
}

// manageRemoteConfigs(onRemoteConfigReady:) takes an OnRemoteConfigAvailable, not a closure —
// AKSBaseAppDelegate has a private adapter for this internally; outside it, write your own:
private class RemoteConfigReadyBridge: NSObject, OnRemoteConfigAvailable {
    private let onReady: () -> Void
    init(_ onReady: @escaping () -> Void) { self.onReady = onReady }
    func onRemoteConfigReadyToFetch(remoteConfig: RemoteConfig) {
        DispatchQueue.main.async { self.onReady() }
    }
}

setIOSAdHandler(iosAdHandler:)에는 IOSPlatformAdHandler의 구체적인 구현체가 필요합니다. AKSBaseAppDelegate가 내부적으로 사용하는 구현체(AdMob/IronSource/MAX 미디에이션 초기화, AppsFlyer/Adjust 보고 담당)는 SDK 내부 타입이므로, 바로 이런 경우에 사용할 수 있도록 makeDefaultIOSAdHandler()를 통해 제공됩니다.

AKSBaseAppDelegate를 상속하지 않으면 자동으로 처리되는 "애플리케이션 수준 앱 오프닝 광고" 흐름(§4.6)을 사용할 수 없습니다. requestSplashAppOpenAd/disableAppOpenSplashCallback/showAppOpenAdIfAvailable은 AKSBaseAppDelegate 자체의 인스턴스 메서드이며, AppsKitSDK 객체만으로는 접근할 수 없습니다. 또한 이 메서드들의 동작에 필요한 포그라운드/백그라운드 추적은 AKSBaseAppDelegate의 applicationWillEnterForeground/applicationDidBecomeActive/applicationWillResignActive 오버라이드에 구현되어 있습니다. 그래도 앱 오프닝 광고를 사용하려면 앱의 자체 시작 흐름에서 원하는 시점에 AppsKitSDKAdsManagerIOS.instance.loadAppOpen/showAppOpen을 직접 호출하세요(§5, 앱 오프닝 광고).

4.3 SwiftUI App 진입점

앱에서 스토리보드 대신 SwiftUI App 프로토콜을 사용한다면, @UIApplicationDelegateAdaptor로 AppDelegate를 연결하세요. 이 연결을 통해 실제로 application(_:didFinishLaunchingWithOptions:)가 실행됩니다.

swift
import SwiftUI

@main
struct YourApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

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

§4.1의 전체 초기화 과정은 WindowGroup이 렌더링되기 전에 didFinishLaunchingWithOptions 내부에서 동기적으로 실행됩니다. 따라서 UI가 표시되기 전에 광고 브리지와 SDK가 준비됩니다.

4.4 동의 및 광고 초기화

swift
AppsKitSDKAdsManagerIOS.instance.initialize(userHasGivenConsent: true, isCCPAConsent: true)

참조 연동 예제에서는 두 플래그가 모두 true로 하드코딩되어 있으며, UMP/CMP 동의 흐름은 어디에도 연결되어 있지 않습니다. 이는 구현이 빠진 부분이지 권장 사항이 아닙니다. 앱에 GDPR/CCPA가 적용된다면 자체 동의 흐름이나 맞춤 CMP를 실행하고, 하드코딩된 true 대신 실제 사용자의 동의 결과를 이 호출에 전달하세요. Google의 UMP SDK는 이미 Google-Mobile-Ads-SDK를 통해 전이 의존성으로 포함되어 있으므로(§1.2) 호출만 하면 됩니다. IDFA도 필요하다면 §3.3의 ATT 권한 요청과 함께 적용하세요.

4.5 광고 제거 / 인앱 구매(IAP)에 따른 광고 제어

swift
AppsKitSDK.shared.setRemoveAdsStatus(status: true)   // call after a successful purchase/restore
AppsKitSDK.shared.getRemoveAdsStatus()               // check current status

모든 광고 로드/표시 호출에서 이미 내부적으로 이 상태를 확인하므로, 직접 조건을 검사해 제어할 필요가 없습니다. Swift의 접근 패턴도 참고하세요. 이러한 매니저 타입은 모두 정적 .shared 접근자를 갖는 클래스로 노출됩니다(AppsKitSDK.shared, AKSLogManager.shared, PreferencesManager.shared 등). SDK 전반에서 이 패턴을 사용합니다.

4.6 애플리케이션 수준 앱 오프닝 광고

AKSBaseAppDelegate는 포그라운드/백그라운드 전환(applicationWillEnterForeground/applicationDidBecomeActive/applicationWillResignActive)을 자동으로 추적하며, AKS 포털 설정에서 isAppOpenAtApplicationLvl이 활성화되어 있으면 웜 스타트 시 앱 오프닝 광고를 표시합니다. 스플래시 흐름에서 사용할 수 있는 메서드는 다음 세 가지입니다.

swift
// Call from your splash screen — requests and shows an app-open ad
(appDelegate as? AKSBaseAppDelegate)?.requestSplashAppOpenAd(callbacks: myCallbacks, waitTimeInSeconds: 5)

// Stop the splash screen's callback from firing again on subsequent app-open events
(appDelegate as? AKSBaseAppDelegate)?.disableAppOpenSplashCallback()

// Manually trigger "show if one's already loaded and ready" — used internally on resume
(appDelegate as? AKSBaseAppDelegate)?.showAppOpenAdIfAvailable()