Mendukung beberapa jendela dan perangkat foldable

Aplikasi yang mendukung beberapa jendela di iPad atau berjalan di perangkat foldable, seperti iPhone Duo, dapat menampilkan UI di berbagai ukuran jendela dan konfigurasi layar yang dinamis. Di iPad, pengguna dapat berinteraksi dengan beberapa salinan UI aplikasi secara bersamaan dan mengubah ukuran jendela. Pada perangkat foldable, status lipat perangkat menentukan layar yang aktif. Saat dibentangkan, perangkat akan menggunakan layar dalam yang lebih besar. Saat dilipat, perangkat menggunakan layar luar yang lebih kecil.

Panduan ini membahas pemuatan dan rendering iklan di lingkungan multi-aplikasi dan layar foldable.

Prasyarat

Sebelum memulai, selesaikan hal-hal berikut:

Menetapkan scene jendela dalam panggilan iklan

Untuk menerima iklan yang sesuai dengan jendela atau tampilan aktif tertentu, tetapkan objek UIWindowScene aktif ke properti scene pada objek GADRequest. Google Mobile Ads SDK menampilkan iklan yang ukurannya sesuai untuk tampilan tersebut. Di SwiftUI, buat kueri scene yang terhubung untuk scene jendela latar depan yang aktif.

Contoh berikut mengonfigurasi scene jendela, memuat iklan interstisial jika berhasil, dan mencatat pesan error ke dalam log jika gagal:

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;
      }];
}

Dalam mode pengujian, permintaan iklan akan gagal dengan error berikut jika aplikasi multi-scene Anda meminta iklan tanpa meneruskan scene:

<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.

Dalam mode produksi, permintaan iklan akan terisi, tetapi iklan akan gagal ditampilkan jika iklan ditampilkan di jendela yang lebih kecil dari ukuran konten iklan:

<Google> Ad cannot be presented. The full screen ad content size exceeds the current window size.

Membuat panggilan iklan

Saat mengirim permintaan iklan, aplikasi multi-scene memerlukan scene jendela yang valid. Jika scene jendela diisi, buat panggilan iklan menggunakan metode viewDidAppear. Sebaiknya gunakan proses ini karena tampilan belum ditambahkan ke jendela dalam metode viewDidLoad.

Meskipun Anda dapat memanggil metode viewDidAppear lebih dari sekali dalam siklus proses aplikasi, Anda harus menggabungkan panggilan iklan dalam tanda boolean agar hanya berjalan sekali.

Contoh berikut melakukan inisialisasi panggilan iklan dalam metode 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;
  }
}

Menangani pengubahan ukuran jendela

Dimensi jendela berubah saat pengguna mengubah ukuran tampilan di iPad atau melipat dan membentangkan perangkat foldable seperti iPhone Duo. Saat ukuran jendela berubah, pastikan iklan yang dimuat sesuai dengan dimensi yang diperbarui dan muat ulang iklan jika perlu.

Untuk memverifikasi bahwa iklan yang dimuat sesuai dengan dimensi yang diperbarui, gunakan salah satu metode berikut:

Iklan layar penuh

Untuk memverifikasi apakah iklan layar penuh yang dimuat tetap valid untuk ukuran jendela atau status lipat yang diperbarui, gunakan metode canPresentFromRootViewController:error:. Jika pemeriksaan gagal, muat iklan yang ukurannya sesuai untuk tampilan yang diperbarui.

Contoh berikut memeriksa apakah iklan interstisial dapat ditampilkan setelah transisi ukuran dan memuat ulang iklan jika diperlukan:

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];
                        }
                      }];
}

Menangani pengubahan ukuran jendela dan transisi lipat yang mirip dengan rotasi perangkat. Batasi tampilan banner ke properti safeAreaLayoutGuide. Proses ini memungkinkan iklan tetap terlihat jelas di engsel, potongan, dan kolom sistem perangkat. Proses ini juga menghitung ulang ukuran banner adaptif anchor menggunakan lebar area aman yang diperbarui.

Contoh berikut memuat banner adaptif anchor dengan lebar jendela yang diperbarui selama transisi ukuran:

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];
  });
}

Iklan native

Anda mengontrol tata letak iklan native. Tidak seperti banner atau iklan layar penuh, Anda tidak perlu memuat ulang iklan native saat ukuran jendela berubah. Gunakan batasan Auto Layout standar atau tata letak SwiftUI untuk tampilan iklan native agar dapat menyesuaikan dengan perubahan ukuran.