4. 初始化 SDK
4.1 AppDelegate
继承 AKSBaseAppDelegate。这是一个采用模板方法模式的基类,可自动完成 Firebase 配置、AdMob 初始化、SDK 初始化和远程配置引导,并提供多个 open 钩子方法,供应用接入自定义逻辑。
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 方法:
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:):
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 用户同意与广告初始化
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)控制
AppsKitSDK.shared.setRemoveAdsStatus(status: true) // call after a successful purchase/restore
AppsKitSDK.shared.getRemoveAdsStatus() // check current status每次加载或展示广告时,SDK 内部都会检查此状态,无需自行添加判断逻辑。请注意 Swift 的访问方式:这些管理器类型都以类的形式公开,并提供静态 .shared 访问器(AppsKitSDK.shared、AKSLogManager.shared、PreferencesManager.shared 等)。整个 SDK 都采用这种模式。
4.6 应用级开屏广告
AKSBaseAppDelegate 会自动跟踪前后台切换(applicationWillEnterForeground/applicationDidBecomeActive/applicationWillResignActive)。如果 AKS 门户配置中启用了 isAppOpenAtApplicationLvl,则会在热启动时展示开屏广告。启动页流程可使用以下三个方法:
// 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()