Les applications compatibles avec le mode multifenêtre sur iPad ou qui s'exécutent sur des appareils pliables, comme l'iPhone Duo, peuvent afficher l'UI sur des tailles de fenêtre et des configurations d'écran dynamiques. Sur iPad, les utilisateurs peuvent interagir avec plusieurs copies simultanées de l'interface utilisateur d'une application et redimensionner les fenêtres. Sur les appareils pliables, l'état de pliage de l'appareil détermine l'écran actif. Lorsqu'il est déplié, l'appareil utilise l'écran intérieur plus grand. Lorsqu'il est plié, l'appareil utilise l'écran extérieur plus petit.
Ce guide explique comment charger et afficher des annonces dans des environnements multifenêtres et sur des écrans pliables.
Prérequis
Avant de commencer, procédez comme suit :
- Activez la prise en charge des scènes dans votre projet. Pour en savoir plus, consultez Spécifier les scènes compatibles avec votre application.
- Implémentez au moins un format d'annonce :
- Annonce à l'ouverture
Définir la scène de la fenêtre dans une demande d'annonce
Pour recevoir une annonce qui s'adapte à une fenêtre ou à un affichage actif spécifique, attribuez l'objet UIWindowScene actif à la propriété scene de l'objet GADRequest. Google Mobile Ads SDK renvoie une annonce dimensionnée pour cette scène. Dans SwiftUI, interrogez les scènes connectées pour la scène de fenêtre active au premier plan.
L'exemple suivant configure la scène de la fenêtre, charge une annonce interstitielle en cas de réussite et consigne un message d'erreur en cas d'échec :
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 mode test, les demandes d'annonces échouent avec l'erreur suivante si votre application multi-scène demande une annonce sans transmettre de scène :
<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 mode production, la demande d'annonce est satisfaite, mais la présentation de l'annonce échoue si elle est présentée dans une fenêtre plus petite que la taille du contenu de l'annonce :
<Google> Ad cannot be presented. The full screen ad content size exceeds the current window size.
Créer la demande d'annonce
Lors de l'envoi de demandes d'annonces, les applications multiscènes nécessitent une scène de fenêtre valide.
Lorsque la scène de la fenêtre est renseignée, créez des demandes d'annonces à l'aide de la méthode viewDidAppear. Nous vous recommandons de procéder ainsi, car une vue n'est pas encore ajoutée à une fenêtre dans la méthode viewDidLoad.
Bien que vous puissiez appeler la méthode viewDidAppear plusieurs fois au cours du cycle de vie d'une application, vous devez encapsuler la demande d'annonce dans un indicateur booléen pour qu'elle ne s'exécute qu'une seule fois.
L'exemple suivant initialise la demande d'annonce dans la méthode 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;
}
}
Gérer le redimensionnement de la fenêtre
Les dimensions de la fenêtre changent lorsque les utilisateurs redimensionnent les scènes sur iPad ou plient et déplient un appareil pliable tel que l'iPhone Duo. Lorsque la taille de la fenêtre change, vérifiez que les annonces chargées s'adaptent aux nouvelles dimensions et actualisez-les si nécessaire.
Pour vérifier que les annonces chargées correspondent aux dimensions mises à jour, utilisez l'une des méthodes suivantes :
viewWillTransitionToSize:withTransitionCoordinator:: détecte quand la fenêtre du contrôleur de vue pivote, est redimensionnée ou passe d'un état de pliage à un autre.windowScene:didUpdateCoordinateSpace:interfaceOrientation:traitCollection:: pour les changements de scène de fenêtre.
Annonces plein écran
Pour vérifier si une annonce en plein écran chargée reste valide pour la taille de fenêtre ou l'état de pliage mis à jour, utilisez la méthode canPresentFromRootViewController:error:. Si la vérification échoue, chargez une annonce dimensionnée pour la scène mise à jour.
L'exemple suivant vérifie si une annonce interstitielle peut s'afficher après une transition de taille et la recharge si nécessaire :
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];
}
}];
}
Bannières
Gérez le redimensionnement de la fenêtre et les transitions de pliage de la même manière que la rotation de l'appareil. Limitez les vues de la bannière à la propriété safeAreaLayoutGuide. Ce processus permet d'éviter que les annonces ne soient masquées par les charnières, les encoches et les barres système de l'appareil. Ce processus recalcule également la taille de la bannière adaptative ancrée en utilisant la largeur de la zone de sécurité mise à jour.
L'exemple suivant charge une bannière adaptative ancrée avec la largeur de fenêtre mise à jour lors d'une transition de taille :
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];
});
}
Annonces natives
Vous contrôlez la mise en page des annonces natives. Contrairement aux bannières ou aux annonces en plein écran, vous n'avez pas besoin de recharger les annonces natives lorsque la fenêtre est redimensionnée. Utilisez des contraintes de mise en page automatique standards ou des mises en page SwiftUI pour que la vue de l'annonce native s'adapte aux changements de taille.