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,且必须保留,可以直接在自己的 application(_:didFinishLaunchingWithOptions:) 中调用该基类内部使用的相同 AppsKitSDK/AKSKit 方法:

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 内部类型,因此 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 协议而非 storyboard,请通过 @UIApplicationDelegateAdaptor 桥接到你的 AppDelegate——只有这样才会实际执行 application(_:didFinishLaunchingWithOptions:):

swift
import SwiftUI

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

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

§4.1 中的整个初始化流程会在 didFinishLaunchingWithOptions 内同步执行,早于 WindowGroup 渲染——因此,在任何 UI 显示之前,广告桥接层和 SDK 就已准备就绪。

4.4 用户同意与广告初始化

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

参考集成将两个标志都硬编码为 true,并未接入任何 UMP/CMP 用户同意流程。这是尚未完善的部分,并非推荐做法:如果应用受 GDPR/CCPA 约束,请执行自己的用户同意流程(Google 的 UMP SDK 已通过 Google-Mobile-Ads-SDK 作为传递依赖引入,见 §1.2,只需调用即可),或使用自定义 CMP,并将真实的用户选择传入此调用,而不是硬编码的 true。如果还需要 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()