एक से ज़्यादा विंडो और फ़ोल्ड किए जा सकने वाले डिवाइसों के साथ काम करता है

iPad पर एक से ज़्यादा विंडो के साथ काम करने वाले या फ़ोल्ड किए जा सकने वाले डिवाइसों (जैसे, iPhone Duo) पर चलने वाले ऐप्लिकेशन, डाइनैमिक विंडो साइज़ और स्क्रीन कॉन्फ़िगरेशन के हिसाब से यूज़र इंटरफ़ेस (यूआई) दिखा सकते हैं. iPad पर, उपयोगकर्ता किसी ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) की एक साथ कई कॉपी के साथ इंटरैक्ट कर सकते हैं. साथ ही, विंडो का साइज़ बदल सकते हैं. फ़ोल्ड किए जा सकने वाले डिवाइसों पर, डिवाइस के फ़ोल्ड होने की स्थिति से यह तय होता है कि कौनसी स्क्रीन चालू है. अनफ़ोल्ड होने पर, डिवाइस बड़े इनर डिसप्ले का इस्तेमाल करता है. फ़ोल्ड होने पर, डिवाइस छोटे आउटर डिसप्ले का इस्तेमाल करता है.

इस गाइड में, मल्टी-विंडो एनवायरमेंट और फ़ोल्ड किए जा सकने वाले डिसप्ले पर विज्ञापन लोड करने और रेंडर करने के बारे में बताया गया है.

ज़रूरी शर्तें

शुरू करने से पहले, ये काम करें:

विज्ञापन दिखाने के अनुरोध में विंडो सीन सेट करना

किसी खास विंडो या ऐक्टिव डिसप्ले में फ़िट होने वाला विज्ञापन पाने के लिए, ऐक्टिव UIWindowScene ऑब्जेक्ट को GAMRequest ऑब्जेक्ट पर scene प्रॉपर्टी को असाइन करें. Google Mobile Ads SDK, उस सीन के लिए विज्ञापन का साइज़ दिखाता है. SwiftUI में, कनेक्ट किए गए सीन के लिए क्वेरी करें, ताकि फ़ोरग्राउंड में चालू विंडो का सीन मिल सके.

यहां दिए गए उदाहरण में, विंडो सीन को कॉन्फ़िगर किया गया है. साथ ही, विज्ञापन लोड होने पर इंटरस्टीशियल विज्ञापन लोड किया गया है और विज्ञापन लोड न होने पर गड़बड़ी का मैसेज लॉग किया गया है:

Swift

func loadAdManagerInterstitial() async {
  let request = AdManagerRequest()
  request.scene = view.window?.windowScene

  do {
    adManagerInterstitial = try await AdManagerInterstitialAd.load(
      with: "/21775744923/example/interstitial", request: request)
  } catch {
    print("Failed to load interstitial ad with error: \(error.localizedDescription)")
  }
}

SwiftUI

func loadAdManagerInterstitial() async {
  let request = AdManagerRequest()
  request.scene =
    UIApplication.shared.connectedScenes
    .first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene

  do {
    let _ = try await AdManagerInterstitialAd.load(
      with: "/21775744923/example/interstitial", request: request)
  } catch {
    print("Failed to load interstitial ad with error: \(error.localizedDescription)")
  }
}

Objective-C

- (void)loadAdManagerInterstitial {
  GAMRequest *request = [GAMRequest request];
  request.scene = self.view.window.windowScene;

  [GAMInterstitialAd loadWithAdManagerAdUnitID:@"/21775744923/example/interstitial"
                                       request:request
                             completionHandler:^(GAMInterstitialAd *ad, NSError *error) {
                               if (error) {
                                 NSLog(@"Failed to load interstitial ad with error: %@",
                                       [error localizedDescription]);
                                 return;
                               }
                               self.adManagerInterstitial = ad;
                             }];
}

टेस्ट मोड में, विज्ञापन दिखाने के अनुरोध इस गड़बड़ी के साथ फ़ेल हो जाते हैं. ऐसा तब होता है, जब आपका मल्टी-सीन ऐप्लिकेशन, सीन पास किए बिना विज्ञापन दिखाने का अनुरोध करता है:

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

प्रोडक्शन मोड में, विज्ञापन दिखाने का अनुरोध पूरा हो जाता है. हालांकि, अगर विज्ञापन को उसके विज्ञापन के कॉन्टेंट के साइज़ से छोटी विंडो पर दिखाया जाता है, तो विज्ञापन नहीं दिखता:

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

विज्ञापन दिखाने का अनुरोध बनाना

विज्ञापन दिखाने के अनुरोध भेजते समय, मल्टी-सीन ऐप्लिकेशन के लिए एक मान्य विंडो सीन ज़रूरी है. जहां विंडो सीन पॉप्युलेट किया गया है वहां viewDidAppear तरीके का इस्तेमाल करके, विज्ञापन दिखाने के अनुरोध बनाएं. हम इस प्रोसेस का सुझाव इसलिए देते हैं, क्योंकि viewDidLoad तरीके में, व्यू को अब तक विंडो में नहीं जोड़ा गया है.

किसी ऐप्लिकेशन की लाइफ़साइकल में, viewDidAppear तरीके को एक से ज़्यादा बार कॉल किया जा सकता है. हालांकि, विज्ञापन दिखाने के अनुरोध को बूलियन फ़्लैग में रैप करना ज़रूरी है, ताकि वह सिर्फ़ एक बार रन हो.

यहां दिए गए उदाहरण में, 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;
  }
}

विंडो का साइज़ बदलना

जब उपयोगकर्ता iPad पर सीन का साइज़ बदलते हैं या iPhone Duo जैसे फ़ोल्ड किए जा सकने वाले डिवाइस को फ़ोल्ड और अनफ़ोल्ड करते हैं, तो विंडो के डाइमेंशन बदल जाते हैं. विंडो का साइज़ बदलने पर, पुष्टि करें कि लोड किए गए विज्ञापन, अपडेट किए गए डाइमेंशन के हिसाब से फ़िट हों. अगर ज़रूरी हो, तो विज्ञापनों को फिर से लोड करें.

लोड किए गए विज्ञापन, अपडेट किए गए डाइमेंशन के हिसाब से सही हैं या नहीं, इसकी पुष्टि करने के लिए इनमें से किसी एक तरीके का इस्तेमाल करें:

फ़ुल-स्क्रीन विज्ञापन

यह पुष्टि करने के लिए कि लोड किया गया फ़ुल-स्क्रीन विज्ञापन, अपडेट की गई विंडो के साइज़ या फ़ोल्ड की गई स्थिति के लिए मान्य है या नहीं, canPresentFromRootViewController:error: तरीके का इस्तेमाल करें. अगर जांच पूरी नहीं होती है, तो अपडेट किए गए सीन के साइज़ के हिसाब से विज्ञापन लोड करें.

यहां दिए गए उदाहरण से पता चलता है कि साइज़ में बदलाव होने के बाद, इंटरस्टीशियल विज्ञापन दिखाया जा सकता है या नहीं. साथ ही, ज़रूरत पड़ने पर विज्ञापन को फिर से लोड किया जा सकता है या नहीं:

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

विंडो का साइज़ बदलने और फ़ोल्ड ट्रांज़िशन को डिवाइस के रोटेशन की तरह मैनेज करें. बैनर व्यू को safeAreaLayoutGuide प्रॉपर्टी तक सीमित करें. इस प्रोसेस से, विज्ञापनों को डिवाइस के हिंज, कटआउट, और सिस्टम बार से दूर रखा जा सकता है. इस प्रोसेस में, सुरक्षित एरिया की अपडेट की गई चौड़ाई का इस्तेमाल करके, ऐंकर किए गए अडैप्टिव बैनर के साइज़ का फिर से हिसाब लगाया जाता है.

यहां दिए गए उदाहरण में, साइज़ ट्रांज़िशन के दौरान अपडेट की गई विंडो की चौड़ाई के साथ, ऐंकर किया गया अडैप्टिव बैनर लोड किया गया है:

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 = AdManagerRequest()
  request.scene = view.window?.windowScene
  bannerView.load(request)
}

SwiftUI

struct MultiSceneAdManagerBannerView: View {
  var body: some View {
    GeometryReader { geometry in
      let adSize = largeAnchoredAdaptiveBanner(width: geometry.size.width)
      MultiSceneAdManagerBannerViewContainer(adSize: adSize)
        .frame(width: adSize.size.width, height: adSize.size.height)
    }
  }
}

private struct MultiSceneAdManagerBannerViewContainer: UIViewRepresentable {
  let adSize: AdSize

  func makeUIView(context: Context) -> AdManagerBannerView {
    let bannerView = AdManagerBannerView(adSize: adSize)
    let request = AdManagerRequest()
    request.scene =
      UIApplication.shared.connectedScenes
      .first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene
    bannerView.load(request)
    return bannerView
  }

  func updateUIView(_ uiView: AdManagerBannerView, context: Context) {
    if uiView.adSize.size != adSize.size {
      uiView.adSize = adSize
      let request = AdManagerRequest()
      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);

    GAMRequest *request = [GAMRequest request];
    request.scene = self.view.window.windowScene;
    [self.bannerView loadRequest:request];
  });
}

नेटिव विज्ञापन

नेटिव विज्ञापनों के लेआउट को कंट्रोल किया जा सकता है. बैनर या फ़ुल-स्क्रीन विज्ञापनों के उलट, विंडो का साइज़ बदलने पर नेटिव विज्ञापनों को फिर से लोड करने की ज़रूरत नहीं होती. नेटिव विज्ञापन व्यू के लिए, स्टैंडर्ड ऑटो लेआउट कंस्ट्रेंट या SwiftUI लेआउट का इस्तेमाल करें, ताकि साइज़ में होने वाले बदलावों के हिसाब से विज्ञापन को अडजस्ट किया जा सके.