Las aplicaciones que admiten varias ventanas en iPad o que se ejecutan en dispositivos plegables, como el iPhone Duo, pueden mostrar la IU en tamaños de ventana y configuraciones de pantalla dinámicos. En iPad, los usuarios pueden interactuar con varias copias simultáneas de la IU de una app y cambiar el tamaño de las ventanas. En los dispositivos plegables, el estado de plegado determina la pantalla activa. Cuando se despliega, el dispositivo usa la pantalla interior más grande. Cuando está plegado, el dispositivo usa la pantalla exterior más pequeña.
En esta guía, se explica cómo cargar y renderizar anuncios en entornos multiventana y pantallas plegables.
Requisitos previos
Antes de comenzar, completa lo siguiente:
- Habilita la compatibilidad con escenas en tu proyecto. Para obtener más información, consulta Cómo especificar las escenas que admite tu app.
- Implementa, al menos, un formato del anuncio:
- Anuncios de aplicación abierta
Cómo configurar la escena de la ventana en una solicitud de anuncio
Para recibir un anuncio que se ajuste a una ventana o pantalla activa específica, asigna el objeto UIWindowScene activo a la propiedad scene del objeto GADRequest. Google Mobile Ads SDK devuelve un anuncio con el tamaño adecuado para esa escena. En SwiftUI, consulta las escenas conectadas para la escena de la ventana activa en primer plano.
En el siguiente ejemplo, se configura la escena de la ventana, se carga un anuncio intersticial si se realiza correctamente y se registra un mensaje de error si falla:
Swift
func loadInterstitial() async {
let request = Request()
request.scene = view.window?.windowScene
do {
interstitial = try await InterstitialAd.load(
with: "ca-app-pub-3940256099942544/4411468910", request: request)
} catch {
print("Failed to load interstitial ad with error: \(error.localizedDescription)")
}
}
SwiftUI
func loadInterstitial() async {
let request = Request()
request.scene =
UIApplication.shared.connectedScenes
.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene
do {
let _ = try await InterstitialAd.load(
with: "ca-app-pub-3940256099942544/4411468910", request: request)
} catch {
print("Failed to load interstitial ad with error: \(error.localizedDescription)")
}
}
Objective-C
- (void)loadInterstitial {
GADRequest *request = [GADRequest request];
request.scene = self.view.window.windowScene;
[GADInterstitialAd
loadWithAdUnitID:@"ca-app-pub-3940256099942544/4411468910"
request:request
completionHandler:^(GADInterstitialAd *ad, NSError *error) {
if (error) {
NSLog(@"Failed to load interstitial ad with error: %@", [error localizedDescription]);
return;
}
self.interstitial = ad;
}];
}
En el modo de prueba, las solicitudes de anuncios fallan con el siguiente error si tu app de varias escenas solicita un anuncio sin pasar una escena:
<Google> Invalid Request. The GADRequest scene property should be set for
applications that support multi-scene. Treating the unset property as an error
while in test mode.
En el modo de producción, la solicitud de anuncio se completa, pero no se presenta el anuncio si se muestra en una ventana más pequeña que el tamaño del contenido del anuncio:
<Google> Ad cannot be presented. The full screen ad content size exceeds the current window size.
Crea la solicitud de anuncio
Cuando se envían solicitudes de anuncios, las aplicaciones de varias escenas requieren una escena de ventana válida.
Donde se propaga la escena de la ventana, crea solicitudes de anuncios con el método viewDidAppear. Recomendamos este proceso porque aún no se agrega una vista a una ventana en el método viewDidLoad.
Si bien puedes llamar al método viewDidAppear más de una vez en el ciclo de vida de una app, debes unir la solicitud de anuncio en una marca booleana para que se ejecute solo una vez.
En el siguiente ejemplo, se inicializa la solicitud de anuncio en el método viewDidAppear:
Swift
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if !requestInitialized {
Task {
await loadInterstitial()
}
requestInitialized = true
}
}
Objective-C
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (!_requestInitialized) {
[self loadInterstitial];
_requestInitialized = YES;
}
}
Cómo controlar el cambio de tamaño de la ventana
Las dimensiones de la ventana cambian cuando los usuarios cambian el tamaño de las escenas en el iPad o pliegan y despliegan un dispositivo plegable, como el iPhone Duo. Cuando cambie el tamaño de la ventana, verifica que los anuncios cargados se ajusten a las dimensiones actualizadas y vuelve a cargarlos si es necesario.
Para verificar que los anuncios cargados se ajusten a las dimensiones actualizadas, usa cualquiera de los siguientes métodos:
viewWillTransitionToSize:withTransitionCoordinator:: Detecta cuando la ventana del controlador de vista rota, cambia de tamaño o realiza transiciones entre estados de plegado.windowScene:didUpdateCoordinateSpace:interfaceOrientation:traitCollection:: para los cambios de escena de la ventana.
Anuncios de pantalla completa
Para verificar si un anuncio de pantalla completa cargado sigue siendo válido para el tamaño de la ventana o el estado de plegado actualizados, usa el método canPresentFromRootViewController:error:. Si la verificación falla, carga un anuncio con el tamaño de la escena actualizada.
En el siguiente ejemplo, se verifica si se puede mostrar un anuncio intersticial después de una transición de tamaño y, si es necesario, se vuelve a cargar el anuncio:
Swift
override func viewWillTransition(
to size: CGSize,
with coordinator: UIViewControllerTransitionCoordinator
) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: nil) { [weak self] _ in
guard let self else { return }
do {
try self.interstitial?.canPresent(from: self)
} catch {
Task {
await self.loadInterstitial()
}
}
}
}
Objective-C
- (void)viewWillTransitionToSize:(CGSize)size
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
[coordinator
animateAlongsideTransition:nil
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
if (![self.interstitial canPresentFromRootViewController:self error:nil]) {
[self loadInterstitial];
}
}];
}
Anuncios en forma de banner
Controla el cambio de tamaño de la ventana y las transiciones de plegado de manera similar a la rotación del dispositivo. Limita las vistas de banners a la propiedad safeAreaLayoutGuide. Este proceso permite que los anuncios se mantengan alejados de las bisagras, los recortes y las barras del sistema del dispositivo. Este proceso también vuelve a calcular el tamaño del banner adaptable fijo con el ancho actualizado del área segura.
En el siguiente ejemplo, se carga un banner adaptable fijo con el ancho de ventana actualizado durante una transición de tamaño:
Swift
override func viewWillTransition(
to size: CGSize,
with coordinator: UIViewControllerTransitionCoordinator
) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: nil) { [weak self] _ in
self?.loadBannerAd()
}
}
@MainActor
func loadBannerAd() {
let frame = view.frame.inset(by: view.safeAreaInsets)
let viewWidth = frame.size.width
bannerView.adSize = largeAnchoredAdaptiveBanner(width: viewWidth)
let request = Request()
request.scene = view.window?.windowScene
bannerView.load(request)
}
SwiftUI
struct MultiSceneBannerView: View {
var body: some View {
GeometryReader { geometry in
let adSize = largeAnchoredAdaptiveBanner(width: geometry.size.width)
MultiSceneBannerViewContainer(adSize: adSize)
.frame(width: adSize.size.width, height: adSize.size.height)
}
}
}
private struct MultiSceneBannerViewContainer: UIViewRepresentable {
let adSize: AdSize
func makeUIView(context: Context) -> BannerView {
let bannerView = BannerView(adSize: adSize)
let request = Request()
request.scene =
UIApplication.shared.connectedScenes
.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene
bannerView.load(request)
return bannerView
}
func updateUIView(_ uiView: BannerView, context: Context) {
if uiView.adSize.size != adSize.size {
uiView.adSize = adSize
let request = Request()
request.scene = uiView.window?.windowScene
uiView.load(request)
}
}
}
Objective-C
- (void)viewWillTransitionToSize:(CGSize)size
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
[coordinator
animateAlongsideTransition:nil
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
[self loadBannerAd];
}];
}
- (void)loadBannerAd {
dispatch_async(dispatch_get_main_queue(), ^{
CGRect frame = UIEdgeInsetsInsetRect(self.view.frame, self.view.safeAreaInsets);
CGFloat viewWidth = frame.size.width;
self.bannerView.adSize = GADLargeAnchoredAdaptiveBannerAdSizeWithWidth(viewWidth);
GADRequest *request = [GADRequest request];
request.scene = self.view.window.windowScene;
[self.bannerView loadRequest:request];
});
}
Anuncios nativos
Tú controlas el diseño de los anuncios nativos. A diferencia de los banners o los anuncios de pantalla completa, no es necesario que vuelvas a cargar los anuncios nativos cuando se cambia el tamaño de la ventana. Usa restricciones estándar de diseño automático o diseños de SwiftUI para que la vista de anuncio nativo se adapte a los cambios de tamaño.