4. Inicialização do SDK
4.1 AppDelegate
Crie uma subclasse de AKSBaseAppDelegate — uma classe base que usa o padrão Template Method e cuida da configuração do Firebase, da inicialização do AdMob e do SDK e da preparação da configuração remota, com alguns hooks open para integrar seu app.
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
}
}Lista completa de hooks open de AKSBaseAppDelegate: setupAdBridge(), isDevMode() -> Bool (padrão: false), isTestMode() -> Bool (padrão: false), defaultConfigJson() -> String? (padrão: nil), timeToFetchRemoteConfigInSeconds() -> Int (padrão: 3600), onConfigsReadyToUse(), configureSDK().
4.2 Inicialização sem herdar de AKSBaseAppDelegate
Criar uma subclasse de AKSBaseAppDelegate não é obrigatório — ela é um wrapper para facilitar a integração. Se seu app já tem um UIApplicationDelegate próprio que precisa manter, chame os mesmos métodos de AppsKitSDK/AKSKit que ela chama internamente, diretamente no seu 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:) precisa de uma implementação concreta de IOSPlatformAdHandler — a que AKSBaseAppDelegate usa internamente (inicialização da mediação AdMob/IronSource/MAX, envio de dados ao AppsFlyer/Adjust) é um tipo interno do SDK, por isso é disponibilizada exatamente para esse caso por meio de makeDefaultIOSAdHandler().
O que você perde ao não criar uma subclasse de AKSBaseAppDelegate: o fluxo automático de "anúncio de abertura do app (App Open) no nível da aplicação" (§4.6) — requestSplashAppOpenAd/disableAppOpenSplashCallback/showAppOpenAdIfAvailable são métodos de instância da própria AKSBaseAppDelegate, não são expostos no objeto AppsKitSDK isolado, e o monitoramento de primeiro e segundo plano que aciona esses métodos fica nas sobrescritas de applicationWillEnterForeground/applicationDidBecomeActive/applicationWillResignActive da própria AKSBaseAppDelegate. Se ainda quiser um anúncio de abertura do app, chame AppsKitSDKAdsManagerIOS.instance.loadAppOpen/showAppOpen por conta própria (§5, App Open) no ponto desejado do seu fluxo de inicialização.
4.3 Ponto de entrada do app em SwiftUI
Se seu app usa o protocolo App do SwiftUI em vez de um storyboard, conecte-o ao seu AppDelegate com @UIApplicationDelegateAdaptor — é isso que faz application(_:didFinishLaunchingWithOptions:) ser executado:
import SwiftUI
@main
struct YourApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}Toda a sequência de inicialização da §4.1 é executada de forma síncrona dentro de didFinishLaunchingWithOptions, antes da renderização de WindowGroup — assim, a ponte de integração de anúncios e o SDK ficam prontos antes de qualquer interface ser exibida.
4.4 Consentimento e inicialização de anúncios
AppsKitSDKAdsManagerIOS.instance.initialize(userHasGivenConsent: true, isCCPAConsent: true)A integração de referência define as duas flags como
truediretamente no código — não há nenhum fluxo de consentimento UMP/CMP integrado. Isso é uma lacuna, não uma recomendação: se seu app estiver sujeito ao GDPR/CCPA, implemente seu próprio fluxo de consentimento (o SDK UMP do Google já é uma dependência transitiva viaGoogle-Mobile-Ads-SDK, §1.2 — basta chamá-lo) ou use uma CMP personalizada e passe a decisão real do usuário para essa chamada, em vez de umtruefixo no código. Combine isso com a solicitação de permissão ATT da §3.3 se também precisar do IDFA.
4.5 Remoção de anúncios / controle por compras no app (IAP)
AppsKitSDK.shared.setRemoveAdsStatus(status: true) // call after a successful purchase/restore
AppsKitSDK.shared.getRemoveAdsStatus() // check current statusToda chamada de carregamento/exibição já verifica esse status internamente — você não precisa adicionar nenhuma verificação por conta própria. Observe o padrão de acesso em Swift: todos esses tipos de gerenciadores são expostos como classes com um acessor estático .shared (AppsKitSDK.shared, AKSLogManager.shared, PreferencesManager.shared, etc.) — você verá esse padrão em todo o SDK.
4.6 Anúncios de abertura do app (App Open) no nível da aplicação
AKSBaseAppDelegate monitora automaticamente as transições entre primeiro e segundo plano (applicationWillEnterForeground/applicationDidBecomeActive/applicationWillResignActive) e exibe um anúncio de abertura do app nas retomadas (warm starts) se a configuração do seu portal AKS tiver isAppOpenAtApplicationLvl habilitado. Três métodos estão disponíveis para o fluxo da sua tela de abertura (splash):
// 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()