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
}
}Полный список методов расширения с модификатором open в AKSBaseAppDelegate: setupAdBridge(), isDevMode() -> Bool (по умолчанию false), isTestMode() -> Bool (по умолчанию false), defaultConfigJson() -> String? (по умолчанию nil), timeToFetchRemoteConfigInSeconds() -> Int (по умолчанию 3600), onConfigsReadyToUse(), configureSDK().
4.2 Инициализация без наследования от AKSBaseAppDelegate
Наследование от AKSBaseAppDelegate необязательно — это лишь удобная обёртка. Если в вашем приложении уже есть собственный UIApplicationDelegate, от которого вы не можете отказаться, вызывайте те же методы AppsKitSDK/AKSKit, которые обёртка использует внутри, напрямую из своего application(_:didFinishLaunchingWithOptions:):
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, вы лишаетесь автоматического показа рекламы App Open на уровне приложения (§4.6). Методы requestSplashAppOpenAd/disableAppOpenSplashCallback/showAppOpenAdIfAvailable принадлежат самому экземпляру AKSBaseAppDelegate и недоступны через объект AppsKitSDK. Отслеживание переходов между активным и фоновым режимами, на котором основана их работа, реализовано в переопределённых методах applicationWillEnterForeground/applicationDidBecomeActive/applicationWillResignActive класса AKSBaseAppDelegate. Если вам всё же нужна реклама App Open, самостоятельно вызывайте AppsKitSDKAdsManagerIOS.instance.loadAppOpen/showAppOpen (§5, App Open) в нужный момент запуска приложения.
4.3 Точка входа приложения SwiftUI
Если ваше приложение использует протокол SwiftUI App вместо storyboard, подключите свой AppDelegate через @UIApplicationDelegateAdaptor — именно это обеспечивает вызов application(_:didFinishLaunchingWithOptions:):
import SwiftUI
@main
struct YourApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}Вся последовательность инициализации из §4.1 выполняется синхронно внутри didFinishLaunchingWithOptions, до отрисовки WindowGroup, поэтому связующий слой для рекламы и SDK готовы ещё до появления интерфейса.
4.4 Согласие пользователя и инициализация рекламы
AppsKitSDKAdsManagerIOS.instance.initialize(userHasGivenConsent: true, isCCPAConsent: true)В эталонной интеграции оба флага жёстко заданы как
true— сценарий получения согласия через UMP/CMP в ней нигде не реализован. Это недоработка, а не рекомендация: если на ваше приложение распространяются требования GDPR/CCPA, реализуйте собственный сценарий получения согласия (UMP SDK от Google уже подключён как транзитивная зависимость черезGoogle-Mobile-Ads-SDK, §1.2 — достаточно его вызвать) или используйте другую CMP и передавайте в этот вызов реальное решение пользователя вместо жёстко заданногоtrue. Если вам также нужен IDFA, дополните этот сценарий запросом разрешения ATT из §3.3.
4.5 Отключение рекламы / учёт встроенных покупок (IAP)
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 Реклама App Open на уровне приложения
AKSBaseAppDelegate автоматически отслеживает переходы между активным и фоновым режимами (applicationWillEnterForeground/applicationDidBecomeActive/applicationWillResignActive) и показывает рекламу App Open при тёплом запуске, если в конфигурации на портале 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()