Приложения, поддерживающие несколько окон на iPad или работающие на складных устройствах, таких как iPhone Duo, могут отображать пользовательский интерфейс в окнах динамического размера и на экранах разной конфигурации. На iPad пользователи могут взаимодействовать с несколькими копиями интерфейса приложения одновременно и изменять размер окон. На складных устройствах активный экран определяется состоянием складывания. В разложенном виде используется внутренний экран большего размера. В сложенном виде устройство использует меньший внешний экран.
В этом руководстве рассказывается, как загружать и показывать объявления в многооконном режиме и на складных экранах.
Требования
Прежде чем начать, выполните следующие действия:
- Включите поддержку сцен в проекте. Подробнее о том, как указать поддерживаемые сцены…
- Используйте хотя бы один формат объявлений:
- Объявления при запуске приложения
Как задать сцену окна в запросе объявления
Чтобы получить объявление, которое подходит для определенного окна или активного экрана, назначьте активный объект 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. Мы рекомендуем этот способ, поскольку в методе 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. При изменении размера окна убедитесь, что загруженные объявления соответствуют новым размерам, и при необходимости перезагрузите их.
Чтобы убедиться, что загруженные объявления соответствуют новым размерам, воспользуйтесь одним из следующих способов:
viewWillTransitionToSize:withTransitionCoordinator:определяет, когда окно контроллера представления поворачивается, меняет размер или переходит между состояниями сгиба.windowScene:didUpdateCoordinateSpace:interfaceOrientation:traitCollection:– для изменений сцены в окне.
Полноэкранные объявления
Чтобы проверить, подходит ли загруженное полноэкранное объявление для нового размера окна или состояния сгиба, используйте метод 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.