אפליקציות שתומכות במספר חלונות ב-iPad או פועלות במכשירים מתקפלים, כמו iPhone Duo, יכולות להציג ממשק משתמש בגדלים דינמיים של חלונות ובהגדרות מסך שונות. ב-iPad, המשתמשים יכולים לבצע פעולות בכמה עותקים בו-זמנית של ממשק המשתמש של האפליקציה ולשנות את גודל החלונות. במכשירים מתקפלים, מצב הקיפול של המכשיר קובע את המסך הפעיל. כשהמכשיר פתוח, הוא משתמש במסך הפנימי הגדול יותר. כשהמכשיר מקופל, הוא משתמש במסך החיצוני הקטן יותר.
במדריך הזה מוסבר איך לטעון ולעבד מודעות בסביבות ריבוי חלונות ובמסכים מתקפלים.
דרישות מוקדמות
לפני שמתחילים, צריך לעשות את הפעולות האלה:
- מפעילים את התמיכה בסצנות בפרויקט. פרטים נוספים זמינים במאמר Specifying the scenes your app supports.
- מטמיעים לפחות פורמט מודעה אחד:
- מודעות בפתיחת אפליקציה
הגדרת סצנת החלון בבקשה להצגת מודעה
כדי לקבל מודעה שמתאימה לחלון ספציפי או לתצוגה פעילה, מקצים את האובייקט UIWindowScene הפעיל למאפיין scene באובייקט GADRequest. Google Mobile Ads SDK מחזירה מודעה בגודל שמתאים לסצנה הזו. ב-SwiftUI, שולחים שאילתה לסצנות המחוברות כדי למצוא את הסצנה של החלון הפעיל בחזית.
בדוגמה הבאה מגדירים את הסצנה של החלון, טוענים מודעת מעברון אם הפעולה מצליחה ומתעדים הודעת שגיאה אם הפעולה נכשלת:
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;
}];
}
במצב בדיקה, בקשות להצגת מודעות נכשלות עם השגיאה הבאה אם האפליקציה עם כמה סצנות מבקשת מודעה בלי להעביר סצנה:
<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. אנחנו ממליצים על התהליך הזה כי תצוגה עדיין לא נוספה לחלון ב-method viewDidLoad.
אפשר להפעיל את השיטה viewDidAppear יותר מפעם אחת במחזור החיים של האפליקציה, אבל צריך לעטוף את הבקשה להצגת מודעה בדגל בוליאני כדי שהיא תפעל רק פעם אחת.
בדוגמה הבאה, הבקשה להצגת מודעה מאותחלת ב-method 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. כשגודל החלון משתנה, צריך לוודא שהמודעות שנטענו מתאימות למידות המעודכנות, ולטעון מחדש את המודעות במקרה הצורך.
כדי לוודא שהמודעות שנטענו מתאימות למידות המעודכנות, אפשר להשתמש באחת מהשיטות הבאות:
-
viewWillTransitionToSize:withTransitionCoordinator:: מזהה מתי החלון של בקר התצוגה מסתובב, משנה את הגודל או עובר בין מצבי קיפול. -
windowScene:didUpdateCoordinateSpace:interfaceOrientation:traitCollection:: לשינויים בסצנות של חלונות.
מודעות במסך מלא
כדי לבדוק אם מודעה במסך מלא שנטענה עדיין מתאימה לגודל החלון או למצב הקיפול המעודכנים, משתמשים ב-method 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 = 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];
});
}
מודעות מותאמות
אתם קובעים את הפריסה של המודעות המותאמות. בניגוד למודעות באנר או למודעות במסך מלא, לא צריך לטעון מחדש מודעות מותאמות כשמשנים את גודל החלון. כדי להתאים את תצוגת המודעה המותאמת לשינויים בגודל, משתמשים באילוצים רגילים של Auto Layout או בפריסות של SwiftUI.