5. Llamadas a los formatos de anuncios
Cada llamada sigue recibiendo una cadena placeholder configurada en el portal de AKS; en tiempo de ejecución, AKS la resuelve en una red y una lista de redes alternativas.
5.1 El patrón de adaptación
Los tipos de callback de anuncios de AKS (AdsCallback, BannerCallback, NativeCallback, RewardedAdCallbacks, AppOpenAdCallbacks) son clases de las que debes heredar y cuyos métodos debes sobrescribir con override, no closures. El patrón habitual (utilizado en todo el código que consume AppsKitSDKAdsManagerIOS) consiste en una pequeña clase adaptadora privada por formato que:
- Hereda del tipo de callback de AKS y llama a
super.init(). - Reenvía cada evento del ciclo de vida según las necesidades de tu propia capa de interfaz de usuario.
- Para los anuncios de banner, nativos y recompensados, encadena por sí misma la carga→visualización; es decir, la sobrescritura de
onBannerLoaded()/onNativeLoaded()/onRewardedLoaded()en el adaptador es la que activa la llamadashow...correspondiente, reutilizandoselftambién como callback del paso de visualización.
private class BannerCallbackAdapter: BannerCallback {
private let onLoaded: () -> Void
private let onFailed: (String) -> Void
private weak var container: UIView?
private let placeholder: String
init(container: UIView, placeholder: String, onLoaded: @escaping () -> Void, onFailed: @escaping (String) -> Void) {
self.container = container
self.placeholder = placeholder
self.onLoaded = onLoaded
self.onFailed = onFailed
super.init()
}
override func onBannerLoaded() {
onLoaded()
guard let vc = UIApplication.topViewController(), let view = container else {
onFailed("No active view controller found")
return
}
AppsKitSDKAdsManagerIOS.instance.showBanner(from: vc, placeholder: placeholder, container: view, callback: self)
}
override func onBannerFailedToLoad() { onFailed("") }
override func onBannerClicked() {}
override func onBannerShown() {}
override func onBannerSizeChanged(bannerSizes: BannerSizes) {}
override func setBannerSize(width: Double, height: Double) {}
}UIApplication.topViewController() (proporcionado por AppsKit.xcframework como extensión de UIApplication) recorre la jerarquía desde el controlador de vista raíz de la ventana clave, pasando por los controladores presentados, de navegación o de pestañas, hasta encontrar la pantalla que está realmente en primer plano. Lo necesitas siempre que una llamada requiera un controlador de vista, pero solo dispongas de un UIView o no tengas ningún contexto de interfaz de usuario.
Intersticial
// Load only
AppsKitSDKAdsManagerIOS.instance.loadInterstitial(from: viewController, placeholder: placeholder, callback: adapter)
// Show a previously loaded interstitial
AppsKitSDKAdsManagerIOS.instance.showInterstitial(from: viewController, placeholder: placeholder, callback: adapter)adapter hereda de AdsCallback:
private class InterstitialCallbackAdapter: AdsCallback {
private let onAdLoaded: () -> Void
private let onAdFailed: () -> Void
init(onAdLoaded: @escaping () -> Void, onAdFailed: @escaping () -> Void) {
self.onAdLoaded = onAdLoaded
self.onAdFailed = onAdFailed
super.init()
}
override func onLoaded() { onAdLoaded() }
override func onFailedToLoad() { onAdFailed() }
override func onAdShown() {}
override func onAdDismissed() {}
override func onAdFailedToShow() {}
}Recompensado
// Separate load/show — chain load→show in your adapter's onRewardedLoaded(), same pattern as banner/native
AppsKitSDKAdsManagerIOS.instance.loadRewarded(from: viewController, placeholder: placeholder, callback: adapter)
AppsKitSDKAdsManagerIOS.instance.showRewarded(from: viewController, placeholder: placeholder, callback: adapter)adapter hereda de RewardedAdCallbacks y encadena onRewardedLoaded() directamente con showRewarded, reutilizando self como callback del paso de visualización:
private class RewardedAdCallbackAdapter: RewardedAdCallbacks {
private let placeholder: String
private let onUserEarnedReward: () -> Void
private let onFailed: (String) -> Void
init(placeholder: String, onUserEarnedReward: @escaping () -> Void, onFailed: @escaping (String) -> Void) {
self.placeholder = placeholder
self.onUserEarnedReward = onUserEarnedReward
self.onFailed = onFailed
super.init()
}
override func onRewardedLoaded() {
guard let vc = UIApplication.topViewController() else {
onFailed("No active view controller found")
return
}
AppsKitSDKAdsManagerIOS.instance.showRewarded(from: vc, placeholder: placeholder, callback: self)
}
override func onAdRewarded() { onUserEarnedReward() }
override func onRewardedCompleted() { onUserEarnedReward() }
override func onAdRewardedAdDismissed() {}
override func onRewardedAdLoadFailure() { onFailed("Failed to load rewarded ad") }
override func onRewardedFailedToShow() { onFailed("Failed to show rewarded ad") }
}AKS también expone
loadAndShowRewarded(from:placeholder:callback:)enAppsKitSDKAdsManagerIOSpara cargar y mostrar en una sola llamada. Recibe unRewardedLoadAndShowCallback, un protocolo que solo incluyeonRewardedAdSuccess()/onRewardedAdFailed()(no necesitasuper.init(), ya que es un protocolo, no una clase abstracta). Usa el par de llamadas independientesloadRewarded/showRewardedanterior cuando necesites cargar el anuncio con antelación y mostrarlo después; usaloadAndShowRewardedcuando siempre lo muestres inmediatamente después de cargarlo.
Apertura de la aplicación
AppsKitSDKAdsManagerIOS.instance.loadAppOpen(placeholder: placeholder, callback: adapter)
AppsKitSDKAdsManagerIOS.instance.showAppOpen(from: viewController, placeholder: placeholder, callback: adapter)adapter hereda de AppOpenAdCallbacks:
private class AppOpenCallbackAdapter: AppOpenAdCallbacks {
private let onAdLoaded: () -> Void
private let onAdFailed: () -> Void
init(onAdLoaded: @escaping () -> Void, onAdFailed: @escaping () -> Void) {
self.onAdLoaded = onAdLoaded
self.onAdFailed = onAdFailed
super.init()
}
override func onLoaded() { onAdLoaded() }
override func onFailedToLoad() { onAdFailed() }
override func onAdShown() {}
override func onDismiss() {}
override func onAdFailToShow() {}
}Este es el flujo manual para los anuncios de apertura de la aplicación. Para que AKS los gestione automáticamente a nivel de aplicación mediante la configuración remota, utiliza el flujo integrado de
AKSBaseAppDelegate(§4.6).
Banner
AppsKitSDKAdsManagerIOS.instance.loadBanner(from: viewController, placeholder: placeholder, callback: adapter)
AppsKitSDKAdsManagerIOS.instance.showBanner(from: viewController, placeholder: placeholder, container: bannerContainerView, callback: adapter)adapter hereda de BannerCallback; consulta la definición completa de BannerCallbackAdapter en §5.1, que encadena onBannerLoaded() directamente con showBanner.
BannerSizes: BANNER (320×50), LARGE_BANNER (320×100), MEDIUM_RECTANGLE (300×250), FULL_BANNER (468×60).
Nativo
AppsKitSDKAdsManagerIOS.instance.loadNative(from: viewController, placeholder: placeholder, isShowInScrollView: true, callback: adapter)
AppsKitSDKAdsManagerIOS.instance.showNative(
from: viewController, container: nativeContainerView, placeholder: placeholder,
res: nil, isShowInScrollView: true, callback: adapter
)
// Show the native ad using the design you created for this placeholder in the
// AKS portal, instead of an XIB — see below.
AppsKitSDKAdsManagerIOS.instance.showTemplatedNative(
from: viewController, container: nativeContainerView, placeholder: placeholder,
isShowInScrollView: true, callback: adapter
)showTemplatedNative se utiliza con placeholders cuyo diseño de anuncio nativo se ha creado y asignado en el portal de AKS, en lugar de en tu aplicación. No incluye ningún parámetro res, porque no tienes que proporcionar el diseño. AKS determina qué plantilla del portal corresponde a este placeholder, la descarga (se almacena en caché tras la primera descarga) y la utiliza para renderizar el anuncio nativo mediante el mismo flujo de carga y visualización que usa showNative. Si el placeholder no tiene ninguna plantilla asignada o no se puede descargar, AKS recurre a su propio diseño nativo predeterminado integrado en lugar de hacer que el anuncio falle. Por tanto, siempre puedes llamar a este método con seguridad, incluso antes de configurar una plantilla en el portal.
adapter hereda de NativeCallback y encadena onNativeLoaded() directamente con showNative, siguiendo el mismo patrón que BannerCallbackAdapter:
private class NativeCallbackAdapter: NativeCallback {
private weak var container: UIView?
private let placeholder: String
private let onAdLoaded: () -> Void
private let onAdFailed: (String) -> Void
init(container: UIView, placeholder: String, onAdLoaded: @escaping () -> Void, onAdFailed: @escaping (String) -> Void) {
self.container = container
self.placeholder = placeholder
self.onAdLoaded = onAdLoaded
self.onAdFailed = onAdFailed
super.init()
}
override func onNativeLoaded() {
onAdLoaded()
guard let vc = UIApplication.topViewController(), let view = container else {
onAdFailed("No active view controller found")
return
}
AppsKitSDKAdsManagerIOS.instance.showNative(
from: vc, container: view, placeholder: placeholder,
res: nil, isShowInScrollView: true, callback: self
)
}
override func onNativeFailedToLoad() { onAdFailed("") }
override func onNativeClicked() {}
override func onNativeShown() {}
}Promoción de funcionalidades
La promoción de funcionalidades se gestiona a través de AppsKitSDKAdsManagerIOS, igual que los demás formatos:
// Optional — exclude features the user already has unlocked from being promoted
AppsKitSDKAdsManagerIOS.instance.setFeaturesAvailable(availableFeatures: ["premium_theme", "no_ads"])
AppsKitSDKAdsManagerIOS.instance.showFeaturePromotion(
from: viewController,
placeholder: placeholder,
callback: adapter
)adapter implementa OnFeaturePromotionClicked, que es un protocolo, no una clase abstracta, por lo que no necesita super.init():
private class FeaturePromotionAdapter: NSObject, OnFeaturePromotionClicked {
private let onClicked: (String) -> Void
private let onFailed: (String) -> Void
init(onClicked: @escaping (String) -> Void, onFailed: @escaping (String) -> Void) {
self.onClicked = onClicked
self.onFailed = onFailed
}
func onFeaturePromotionClicked(targetScreen: String) { onClicked(targetScreen) }
func onFailToShowFeaturePromotion(errorMessage: String) { onFailed(errorMessage) }
}