自定义的原生广告格式

自定义广告格式

与系统定义的原生广告格式一样,自定义的原生广告格式也是使用 GADAdLoader 对象加载的。初始化 GADAdLoader 时,在 adTypes 数组中包含 GADAdLoaderAdTypeCustomNative 常量会将其配置为在加载广告时请求自定义的原生广告格式。

GADCustomNativeAdLoaderDelegate

用于加载自定义格式的协议有两种方法。第一种供 GADAdLoader 使用,用于找出它应请求的格式 ID:

Swift

public func customNativeAdFormatIDs(for adLoader: GADAdLoader) -> [Any]

Objective-C

- (NSArray *)customNativeAdFormatIDsForAdLoader:(GADAdLoader *)adLoader;

每个自定义的原生广告格式都有用于自我标识的相应格式 ID。调用此方法时,您的应用应返回一个数组,其中包含准备展示的广告的格式 ID。

第二条消息在自定义原生广告加载后发送,与系统定义的格式非常相似:

Swift

public func adLoader(_ adLoader: GADAdLoader,
    didReceive customNativeAd: GADCustomNativeAd)

Objective-C

- (void)adLoader:(GADAdLoader *)adLoader
    didReceiveCustomNativeAd:(GADCustomNativeAd *)customNativeAd;

格式 ID

您可以在 Ad Manager 界面的原生部分下的投放下拉菜单中找到用于唯一引用自定义原生广告格式的格式 ID:

每个自定义原生广告的格式 ID 都会显示在其名称旁边。点击其中一个名称可以转到详细信息屏幕,该屏幕显示了格式字段的相关信息:

在这里,您可以添加、修改和移除各个字段。请注意每项资产的名称。名称是用于在展示自定义原生广告格式时获取每个素材资源数据的键。

展示自定义的原生广告格式

自定义原生广告格式与系统定义的原生广告格式的不同之处在于,发布商有权定义自己的构成广告的素材资源列表。因此,展示自定义原生广告的过程与系统定义的格式的展示流程在以下几个方面有所不同:

  1. 由于 GADCustomNativeAd 用于处理您创建的任何自定义原生广告格式,因此它没有已命名的素材资源存取器,而是提供了 imageForKey:stringForKey: 等将字段名称作为参数的方法。
  2. 没有 GADNativeAdView 等可用于 GADCustomNativeAd 的专用广告视图类。您可以随意使用任何有助于改善用户体验的视图。
  3. 由于没有专用的广告视图类,因此您无需注册任何用于展示广告素材资源的视图。

以下是能够展示简单的自定义原生广告的广告视图示例:

MySimpleNativeAdView.h

Swift

import UIKit
import GoogleMobileAds

/// Custom native ad view class with format ID 10063170.
class MySimpleNativeAdView: UIView {

  /// Weak references to this ad's asset views.
  @IBOutlet weak var headlineView: UILabel!
  @IBOutlet weak var mainImageView: UIImageView!
  @IBOutlet weak var captionView: UILabel!

  ...

  /// Populates the ad view with the custom native ad object.
  func populateWithCustomNativeAd(_ customNativeAd: GADCustomNativeAd) {
    ...
  }
}

Objective-C

@import UIKit;
@import GoogleMobileAds;

/// View representing a custom native ad format with format ID 10063170.
@interface MySimpleNativeAdView : UIView

// Weak references to this ad's asset views.
@property(weak, nonatomic) IBOutlet UILabel *headlineView;
@property(weak, nonatomic) IBOutlet UIImageView *mainImageView;
@property(weak, nonatomic) IBOutlet UILabel *captionView;

/// Populates the ad view with the custom native ad object.
- (void)populateWithCustomNativeAd:(GADCustomNativeAd *)customNativeAd;

@end

MySimpleNativeAdView.m(节选)

Swift

...
func populateWithCustomNativeAd(_ customNativeAd: GADCustomNativeAd) {
  self.customNativeAd = customNativeAd

  // Populate the custom native ad assets.
  headlineView.text = self.customNativeAd.stringForKey("Headline")
  mainImageView.image = self.customNativeAd.imageForKey("MainImage")?.image
  captionView.text = self.customNativeAd.stringForKey("Caption")
}
...

Objective-C

...
- (void)populateWithCustomNativeAd:(GADCustomNativeAd *)customNativeAd {
  self.customNativeAd = customNativeAd;

  // Populate the custom native ad assets.
  self.headlineView.text = [customNativeAd stringForKey:@"Headline"];
  self.mainImageView.image = [customNativeAd imageForKey:@"MainImage"].image;
  self.captionView.text = [customNativeAd stringForKey:@"Caption"];
}
...

呈现“广告选择”图标

根据支持《数字服务法案》(DSA) 的规定,在欧洲经济区 (EEA) 投放的预订型广告必须包含“广告选择”图标和指向 Google 的“关于此广告”页面的链接。植入自定义原生广告时,您需要负责呈现“广告选择”图标。在呈现主要广告素材资源时,请务必采取措施来呈现“广告选择”图标并为其设置点击监听器。

以下示例呈现了“广告选择”图标并配置适当的点击行为。

Swift

class MySimpleNativeAdView: UIView {
  @IBOutlet weak var adChoicesView: UIImageView!

  override func awakeFromNib() {
    super.awakeFromNib()

    // Enable clicks on AdChoices.
    adChoicesView.addGestureRecognizer(
      UITapGestureRecognizer(
        target: self,
        action: #selector(performClickOnAdChoices(_:))))
    adChoicesView.isUserInteractionEnabled = true
  }

  @objc func performClickOnAdChoices(_ sender: UIImage!) {
    customNativeAd.performClickOnAsset(withKey:
      GADNativeAssetIdentifier.adChoicesViewAsset.rawValue)
  }

  func populate(withCustomNativeAd customNativeAd: GADCustomNativeAd) {

    // Render the AdChoices image.
    let adChoicesKey = GADNativeAssetIdentifier.adChoicesViewAsset.rawValue
    let adChoicesImage = customNativeAd.image(forKey: adChoicesKey)?.image
    adChoicesView.image = adChoicesImage
    adChoicesView.isHidden = adChoicesImage == nil
    ...
  }
}

Objective-C

@interface MySimpleNativeAdView ()

@property(nonatomic, weak) IBOutlet UIImageView *adChoicesView;

@end

@implementation MySimpleNativeAdView

- (void)awakeFromNib {
  [super awakeFromNib];
  // Enable clicks on AdChoices.
  [self.adChoicesView addGestureRecognizer:[[UITapGestureRecognizer alloc]
                                            initWithTarget:self
                                            action:@selector(performClickOnAdChoices:)]];
  self.adChoicesView.userInteractionEnabled = YES;
}

- (void)performClickOnAdChoices:(UITapGestureRecognizer *)sender {
    [self.customNativeAd performClickOnAssetWithKey:GADNativeAdChoicesViewAsset];
}

- (void)populateWithCustomNativeAd:(GADCustomNativeAd *)customNativeAd {
  // Render the AdChoices image.
  GADNativeAdImage *adChoicesAsset = [customNativeAd
    imageForKey:GADNativeAdChoicesViewAsset];
  self.adChoicesView.image = adChoicesAsset.image;
  self.adChoicesView.hidden = (adChoicesAsset == nil);
  ...
}

自定义原生广告格式的原生视频

创建自定义格式时,您可以选择让格式适用于视频。

在应用实现中,您可以使用 GADCustomNativeAd.mediaView 属性获取视频的视图。然后将此视图添加到视图层次结构中。如果广告没有视频内容,则需要制定备用方案,以便在没有视频的情况下也能展示广告。

以下示例会检查广告是否包含视频内容,如果没有视频,会在相应位置展示图片:

Swift

...
  /// Populates the ad view with the custom native ad object.
  func populate(withCustomNativeAd customNativeAd: GADCustomNativeAd) {
    if customNativeAd.videoController.hasVideoContent(),
      let mediaView = customNativeAd.mediaView {
      updateMainView(mediaView)
    } else {
      // Assumes your native format has an image asset with the name MainImage.
      let image: UIImage? = customNativeAd.image(forKey: "MainImage")?.image
      updateMainView(UIImageView(image: image))
    }
  }

  private func updateMainView(_ mainView:UIView) {
    // Assumes you have a placeholder view for your media content.
    // Remove all the placeholder's subviews.
    for subview: UIView in mainPlaceholder.subviews {
      subview.removeFromSuperview()
    }
    mainPlaceholder.addSubview(mainView)
    // Size the media view to fill our container size.
    mainView.translatesAutoresizingMaskIntoConstraints = false
    let viewDictionary: [AnyHashable: Any] = ["mainView":mainView]
    mainPlaceholder.addConstraints(NSLayoutConstraint.constraints(
      withVisualFormat: "H:|[mainView]|", options: [], metrics: nil,
      views: viewDictionary as? [String : Any] ?? [String : Any]()))
    mainPlaceholder.addConstraints(NSLayoutConstraint.constraints(
      withVisualFormat: "V:|[mainView]|", options: [], metrics: nil,
      views: viewDictionary as? [String : Any] ?? [String : Any]()))
  }
...

Objective-C

...
- (void)populateWithCustomNativeAd:(GADCustomNativeAd *)ad {
  UIView *mainView = nil;
  if (ad.videoController.hasVideoContent) {
    mainView = ad.mediaView;
  } else {
    // Assumes your native format has an image asset with the name MainImage.
    UIImage *image = [ad imageForKey:@"MainImage"].image;
    mainView = [[UIImageView alloc] initWithImage:image];
  }
  // Assumes you have a placeholder view for your media content.
  for (UIView *subview in self.mainPlaceholder.subviews) {
    [subview removeFromSuperview];
  }
  [self.mainPlaceholder addSubview:mainView];

  // Size the main view to fill our container size.
  [mainView setTranslatesAutoresizingMaskIntoConstraints:NO];
  NSDictionary *viewDictionary = NSDictionaryOfVariableBindings(mainView);
  [self.mainPlaceholder
      addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[mainView]|"
                                                             options:0
                                                             metrics:nil
                                                               views:viewDictionary]];
}
...

如需详细了解如何自定义自定义原生广告的视频体验,请参阅 GADVideoController

您可以下载 Ad Manager 自定义呈现示例,以获取实际投放的原生视频广告示例。

处理自定义原生广告的点击次数和展示次数

对于自定义原生广告格式,您的应用负责记录展示次数并向 SDK 报告点击事件。

记录展示次数

若要记录自定义原生广告的展示次数,只需在相应 GADCustomNativeAd 上调用 recordImpression 方法即可:

Swift

myCustomNativeAd.recordImpression()

Objective-C

[myCustomNativeAd recordImpression];

如果您的应用不小心针对同一广告多次调用了该方法,SDK 会阻止系统针对单个请求记录重复展示。

报告点击次数

要向 SDK 报告在素材资源视图中发生了点击,请在相应 GADCustomNativeAd 上调用 performClickOnAssetWithKey: 方法,并传入获得点击的素材资源的名称。例如,如果您的自定义格式中有一个名为“MainImage”的素材资源,并且您希望报告与该素材资源对应的视图上的点击,则代码如下所示:

Swift

myCustomNativeAd.performClickOnAsset(withKey: "MainImage")

Objective-C

[myCustomNativeAd performClickOnAssetWithKey:@"MainImage"];

请注意,您不需要为广告所关联的每个素材资源视图都调用此方法。例如,如果您有另一个名为“Caption”的素材资源,该素材资源只作展示之用,不会获得用户的点击或点按,则您的应用就不需要针对该视图调用 performClickOnAssetWithKey:

响应自定义点击操作

GADCustomNativeAd 具有一个类型为 GADNativeAdCustomClickHandlercustomClickHandler 属性

Swift

typealias GADNativeAdCustomClickHandler = (assetID: String) -> Void

Objective-C

typedef void (^GADNativeAdCustomClickHandler)(NSString *assetID);

这是一个可接受 assetID 作为输入参数的块 (Objective-C) / closure (Swift),用于标识用户点击的素材资源。

当自定义原生广告上发生点击时,SDK 可能会作出的响应有三种,具体尝试的响应顺序如下:

  1. 调用 Objective-C 的 customClickHandler 代码块或 Swift 的闭包(如果已设置)。
  2. 循环遍历广告的深层链接网址,并打开第一个可找到匹配应用的网址。
  3. 打开浏览器并转至广告的传统目标网址。

customClickHandler 属性接受 Objective-C 的块和 Swift 的闭包。如果您设置了块或闭包,SDK 将运行它,并且不会采取进一步操作。但是,如果您设置了 nil 值,SDK 将回退到在广告中注册的深层链接和/或目标网址。

自定义点击处理程序可让您的应用自行决定响应点击的最佳操作,无论是更新界面、显示其他视图控制器,还是仅记录点击。以下是显示提醒的示例:

Swift

myCustomNativeAd.customClickHandler = { assetID in
  if assetID == "MainImage" {
    let alertView = UIAlertView(title: "Custom Click",
        message: "You just clicked on the image!",
        delegate: self,
        cancelButtonTitle: "OK")
    alertView.alertViewStyle = .default
    alertView.show()
  }
}
myCustomNativeAd.performClickOnAsset(withKey: "MainImage")

Objective-C

[self.customNativeAd setCustomClickHandler:^(NSString *assetID){
  if ([assetID isEqualToString:@"MainImage"]) {
    [[[UIAlertView alloc] initWithTitle:@"Custom Click"
                                message:@"You just clicked on the image!"
                               delegate:self
                      cancelButtonTitle:@"OK"
                      otherButtonTitles:nil] show];
  }
}];
[self.customNativeAd performClickOnAssetWithKey:@"MainImage"];

测试原生广告代码

直销广告

如果您想测试直销原生广告的呈现效果,可以使用此 Ad Manager 广告单元 ID:

/6499/example/native

它已配置为投放示例应用安装广告和内容广告以及包含以下素材资源的自定义原生广告格式:

  • 标题(文字)
  • 主图片(图片)
  • 图片说明(文字)

原生补余广告

要测试原生补余广告的行为,请使用此Ad Manager 广告单元:

/6499/example/native-backfill

它将投放包含“广告选择”叠加层的示例应用安装广告和内容广告。

在实际投放前,请务必更新代码,使其引用您的实际广告单元 ID 和格式 ID!