Как показывать нативные объявления

Выберите платформу: Android iOS Android (устаревшая версия)

Как показывать нативные объявления в системном формате

Когда нативное объявление загружается, ваше приложение получает объект нативного объявления с помощью одного из сообщений протокола GADAdLoaderDelegate. После этого приложение должно показать объявление (но не обязательно сразу). Чтобы упростить показ объявлений в системных форматах, в SDK есть полезные ресурсы.

GADNativeAdView

Для GADNativeAd существует соответствующий класс "просмотр объявления": GADNativeAdView. Этот класс просмотра объявлений – UIView, который издатели должны использовать для показа объявлений. Например, одно свойство GADNativeAdView может отображать один экземпляр свойства GADNativeAd. Каждый из объектов UIView, используемых для показа объектов объявления, должен быть дочерним представлением объекта GADNativeAdView.

Если вы показываете объявление в UITableView, например, иерархия View для одной из ячеек может выглядеть следующим образом:

Класс GADNativeAdView также предоставляет IBOutlets, используемый для регистрации представления, которое применяется к каждому отдельному объекту, и метод для регистрации самого объекта GADNativeAd. Регистрация представлений таким образом позволяет SDK автоматически выполнять следующие задачи:

  • Регистрация кликов.
  • Регистрация показов (когда на экране появляется первый пиксель).
  • Показ оверлея "Выбор рекламы".

Значок "Выбор рекламы"

Для нативных объявлений, размещаемых косвенно (через заполнение AdMob или через Ad Exchange или AdSense), оверлей "Выбор рекламы" добавляется SDK. Оставьте место в предпочтительном углу нативного объявления для автоматически вставляемого значка "Выбор рекламы". Также убедитесь, что оверлей «Выбор рекламы» размещен на контенте таким образом, чтобы значок был хорошо виден. Подробнее о нативных объявлениях с алгоритмической продажей…

Пометка рекламы

При показе нативных объявлений, купленных через алгоритмические системы, необходимо показывать пометку рекламы, чтобы пользователи понимали, что видят рекламу.

Пример кода

В этом разделе рассказывается, как показывать нативные объявления с помощью представлений, динамически загружаемых из XIB-файлов. Этот подход может быть очень полезен при использовании GADAdLoaders, настроенного на запрос нескольких форматов.

Как размещать объекты UIView

Сначала нужно создать макет UIViews, в котором будут показываться объекты нативных объявлений. Это можно сделать в Interface Builder так же, как и при создании любого другого файла XIB. Вот как может выглядеть макет нативного объявления:

Обратите внимание на значение параметра "Специальный класс" в правом верхнем углу изображения. Установлено значение

GADNativeAdView. Это класс просмотра объявлений, который используется для показа GADNativeAd.

Вам также нужно будет задать специальный класс для элемента GADMediaView, который используется для показа видео или изображения в объявлении.

После того как вы разместите представления и назначите макету правильный класс представления объявлений, свяжите выходные объекты представления объявлений с созданными вами UIViews. Вот как можно связать точки выхода объектов из просмотра объявлений с UIViews, созданными для объявления:

На панели объектов объекты в GADNativeAdView связаны с объектами UIViews, размещенными в Interface Builder. Это позволяет SDK понять, какой объект показывается в каком UIView. Также важно помнить, что эти источники представляют собой мнения, на которые можно нажать в объявлении.

Показ объявления

После того как макет будет готов и магазины будут связаны, добавьте в приложение следующий код, который будет показывать объявление после его загрузки:

Swift

func adLoader(_ adLoader: AdLoader, didReceive nativeAd: NativeAd) {
  // ...

  // Set ourselves as the native ad delegate to be notified of native ad events.
  nativeAd.delegate = self

  // Populate the native ad view with the native ad assets.
  // The headline and mediaContent are guaranteed to be present in every native ad.
  (nativeAdView.headlineView as? UILabel)?.text = nativeAd.headline
  nativeAdView.mediaView?.mediaContent = nativeAd.mediaContent

  // Some native ads will include a video asset, while others do not. Apps can use the
  // GADVideoController's hasVideoContent property to determine if one is present, and adjust their
  // UI accordingly.
  let mediaContent = nativeAd.mediaContent
  if mediaContent.hasVideoContent {
    // By acting as the delegate to the GADVideoController, this ViewController receives messages
    // about events in the video lifecycle.
    mediaContent.videoController.delegate = self
    videoStatusLabel.text = "Ad contains a video asset."
  } else {
    videoStatusLabel.text = "Ad does not contain a video."
  }

  // This app uses a fixed width for the GADMediaView and changes its height to match the aspect
  // ratio of the media it displays.
  if let mediaView = nativeAdView.mediaView, nativeAd.mediaContent.aspectRatio > 0 {
    let aspectRatioConstraint = NSLayoutConstraint(
      item: mediaView,
      attribute: .width,
      relatedBy: .equal,
      toItem: mediaView,
      attribute: .height,
      multiplier: CGFloat(nativeAd.mediaContent.aspectRatio),
      constant: 0)
    mediaView.addConstraint(aspectRatioConstraint)
    nativeAdView.layoutIfNeeded()
  }

  // These assets are not guaranteed to be present. Check that they are before
  // showing or hiding them.
  (nativeAdView.bodyView as? UILabel)?.text = nativeAd.body
  nativeAdView.bodyView?.isHidden = nativeAd.body == nil

  (nativeAdView.callToActionView as? UIButton)?.setTitle(nativeAd.callToAction, for: .normal)
  nativeAdView.callToActionView?.isHidden = nativeAd.callToAction == nil

  (nativeAdView.iconView as? UIImageView)?.image = nativeAd.icon?.image
  nativeAdView.iconView?.isHidden = nativeAd.icon == nil

  (nativeAdView.starRatingView as? UIImageView)?.image = imageOfStars(from: nativeAd.starRating)
  nativeAdView.starRatingView?.isHidden = nativeAd.starRating == nil

  (nativeAdView.storeView as? UILabel)?.text = nativeAd.store
  nativeAdView.storeView?.isHidden = nativeAd.store == nil

  (nativeAdView.priceView as? UILabel)?.text = nativeAd.price
  nativeAdView.priceView?.isHidden = nativeAd.price == nil

  (nativeAdView.advertiserView as? UILabel)?.text = nativeAd.advertiser
  nativeAdView.advertiserView?.isHidden = nativeAd.advertiser == nil

  // In order for the SDK to process touch events properly, user interaction should be disabled.
  nativeAdView.callToActionView?.isUserInteractionEnabled = false

  // Associate the native ad view with the native ad object. This is
  // required to make the ad clickable.
  // Note: this should always be done after populating the ad views.
  nativeAdView.nativeAd = nativeAd
}

SwiftUI

Как создать модель представления

Создайте модель представления, которая загружает нативное объявление и публикует изменения данных нативного объявления:

import GoogleMobileAds

class NativeAdViewModel: NSObject, ObservableObject, NativeAdLoaderDelegate {
  @Published var nativeAd: NativeAd?
  private var adLoader: AdLoader!

  func refreshAd() {
    adLoader = AdLoader(
      adUnitID: "ca-app-pub-3940256099942544/3986624511",
      // The UIViewController parameter is optional.
      rootViewController: nil,
      adTypes: [.native], options: nil)
    adLoader.delegate = self
    adLoader.load(Request())
  }

  func adLoader(_ adLoader: AdLoader, didReceive nativeAd: NativeAd) {
    // Native ad data changes are published to its subscribers.
    self.nativeAd = nativeAd
    nativeAd.delegate = self
  }

  func adLoader(_ adLoader: AdLoader, didFailToReceiveAdWithError error: Error) {
    print("\(adLoader) failed with error: \(error.localizedDescription)")
  }
}

Как создать UIViewRepresentable

Создайте UIViewRepresentable для NativeView и подпишитесь на изменения данных в классе ViewModel:

private struct NativeAdViewContainer: UIViewRepresentable {
  typealias UIViewType = NativeAdView

  // Observer to update the UIView when the native ad value changes.
  @ObservedObject var nativeViewModel: NativeAdViewModel

  func makeUIView(context: Context) -> NativeAdView {
    return
      Bundle.main.loadNibNamed(
        "NativeAdView",
        owner: nil,
        options: nil)?.first as! NativeAdView
  }

  func updateUIView(_ nativeAdView: NativeAdView, context: Context) {
    guard let nativeAd = nativeViewModel.nativeAd else { return }

    // Each UI property is configurable using your native ad.
    (nativeAdView.headlineView as? UILabel)?.text = nativeAd.headline

    nativeAdView.mediaView?.mediaContent = nativeAd.mediaContent

    (nativeAdView.bodyView as? UILabel)?.text = nativeAd.body

    (nativeAdView.iconView as? UIImageView)?.image = nativeAd.icon?.image

    (nativeAdView.starRatingView as? UIImageView)?.image = imageOfStars(from: nativeAd.starRating)

    (nativeAdView.storeView as? UILabel)?.text = nativeAd.store

    (nativeAdView.priceView as? UILabel)?.text = nativeAd.price

    (nativeAdView.advertiserView as? UILabel)?.text = nativeAd.advertiser

    (nativeAdView.callToActionView as? UIButton)?.setTitle(nativeAd.callToAction, for: .normal)

    // For the SDK to process touch events properly, user interaction should be disabled.
    nativeAdView.callToActionView?.isUserInteractionEnabled = false

    // Associate the native ad view with the native ad object. This is required to make the ad
    // clickable.
    // Note: this should always be done after populating the ad views.
    nativeAdView.nativeAd = nativeAd
  }

Добавьте представление в иерархию представлений.

В следующем фрагменте кода показано, как добавить UIViewRepresentable в иерархию представлений:

struct NativeContentView: View {
  // Single source of truth for the native ad data.
  @StateObject private var nativeViewModel = NativeAdViewModel()

  var body: some View {
    ScrollView {
      VStack(spacing: 20) {
        // Updates when the native ad data changes.
        NativeAdViewContainer(nativeViewModel: nativeViewModel)
          .frame(minHeight: 300)  // minHeight determined from xib.

Objective-C

- (void)adLoader:(GADAdLoader *)adLoader didReceiveNativeAd:(GADNativeAd *)nativeAd {
  // ...

  GADNativeAdView *nativeAdView = self.nativeAdView;

  // Set ourselves as the ad delegate to be notified of native ad events.
  nativeAd.delegate = self;

  // Populate the native ad view with the native ad assets.
  // The headline and mediaContent are guaranteed to be present in every native ad.
  ((UILabel *)nativeAdView.headlineView).text = nativeAd.headline;
  nativeAdView.mediaView.mediaContent = nativeAd.mediaContent;

  // This app uses a fixed width for the GADMediaView and changes its height
  // to match the aspect ratio of the media content it displays.
  if (nativeAdView.mediaView != nil && nativeAd.mediaContent.aspectRatio > 0) {
    NSLayoutConstraint *aspectRatioConstraint =
        [NSLayoutConstraint constraintWithItem:nativeAdView.mediaView
                                     attribute:NSLayoutAttributeWidth
                                     relatedBy:NSLayoutRelationEqual
                                        toItem:nativeAdView.mediaView
                                     attribute:NSLayoutAttributeHeight
                                    multiplier:(nativeAd.mediaContent.aspectRatio)
                                      constant:0];
    [nativeAdView.mediaView addConstraint:aspectRatioConstraint];
    [nativeAdView layoutIfNeeded];
  }

  if (nativeAd.mediaContent.hasVideoContent) {
    // By acting as the delegate to the GADVideoController, this ViewController
    // receives messages about events in the video lifecycle.
    nativeAd.mediaContent.videoController.delegate = self;

    self.videoStatusLabel.text = @"Ad contains a video asset.";
  } else {
    self.videoStatusLabel.text = @"Ad does not contain a video.";
  }

  // These assets are not guaranteed to be present. Check that they are before
  // showing or hiding them.
  ((UILabel *)nativeAdView.bodyView).text = nativeAd.body;
  nativeAdView.bodyView.hidden = nativeAd.body ? NO : YES;

  [((UIButton *)nativeAdView.callToActionView) setTitle:nativeAd.callToAction
                                               forState:UIControlStateNormal];
  nativeAdView.callToActionView.hidden = nativeAd.callToAction ? NO : YES;

  ((UIImageView *)nativeAdView.iconView).image = nativeAd.icon.image;
  nativeAdView.iconView.hidden = nativeAd.icon ? NO : YES;

  ((UIImageView *)nativeAdView.starRatingView).image = [self imageForStars:nativeAd.starRating];
  nativeAdView.starRatingView.hidden = nativeAd.starRating ? NO : YES;

  ((UILabel *)nativeAdView.storeView).text = nativeAd.store;
  nativeAdView.storeView.hidden = nativeAd.store ? NO : YES;

  ((UILabel *)nativeAdView.priceView).text = nativeAd.price;
  nativeAdView.priceView.hidden = nativeAd.price ? NO : YES;

  ((UILabel *)nativeAdView.advertiserView).text = nativeAd.advertiser;
  nativeAdView.advertiserView.hidden = nativeAd.advertiser ? NO : YES;

  // In order for the SDK to process touch events properly, user interaction
  // should be disabled.
  nativeAdView.callToActionView.userInteractionEnabled = NO;

  // Associate the native ad view with the native ad object. This is
  // required to make the ad clickable.
  // Note: this should always be done after populating the ad views.
  nativeAdView.nativeAd = nativeAd;
}

Полный пример на GitHub

Полные примеры интеграции нативных объявлений в Swift, SwiftUI и Objective-C можно посмотреть на GitHub.

Расширенный пример нативного объявления на языке Swift Пример нативного объявления на языке SwiftUI Расширенный пример нативного объявления на языке Objective-C

GADMediaView

Объекты изображений и видео показываются пользователям с помощью GADMediaView. Это UIView, которое можно определить в файле XIB или создать динамически. Его следует размещать в иерархии View GADNativeAdView, как и любое другое представление объекта.

Как и в случае с другими объектами, в медиаобъекте должен быть контент. Это значение задается с помощью свойства mediaContent в элементе GADMediaView. Свойство mediaContent объекта GADNativeAd содержит медиаконтент, который можно передать в объект GADMediaView.

Ниже приведен фрагмент кода из примера расширенного нативного объявления (Swift | Objective-C), в котором показано, как заполнить объект GADMediaView нативными объектами объявлений с помощью объекта GADMediaContent из объекта GADNativeAd:

Swift

nativeAdView.mediaView?.mediaContent = nativeAd.mediaContent

Objective-C

nativeAdView.mediaView.mediaContent = nativeAd.mediaContent;

Убедитесь, что в файле конструктора интерфейса для представления нативного объявления в качестве специального класса представления задано значение GADMediaView и что оно подключено к выходу mediaView.

Как изменить режим контента для изображений

При показе изображений класс GADMediaView учитывает свойство UIView contentMode. Чтобы изменить способ масштабирования изображения в GADMediaView, задайте соответствующее значение UIViewContentMode для свойства contentMode объекта GADMediaView.

Например, чтобы заполнить GADMediaView, когда показывается изображение (в объявлении нет видео), выполните следующие действия:

Swift

nativeAdView.mediaView?.contentMode = .scaleAspectFit

Objective-C

nativeAdView.mediaView.contentMode = UIViewContentModeScaleAspectFit;

GADMediaContent

Класс GADMediaContent содержит данные, связанные с медиаконтентом нативного объявления, который показывается с помощью класса GADMediaView. Если задано для свойства GADMediaView mediaContent:

  • Если видеообъект доступен, он буферизируется и начинает воспроизводиться в элементе GADMediaView. Чтобы узнать, доступен ли видеообъект, проверьте hasVideoContent.

  • Если в объявлении нет видеообъекта, объект mainImage скачивается и помещается в GADMediaView.

Дальнейшие действия

Подробнее о конфиденциальности пользователей…