自定义广告格式
与系统定义的原生广告格式一样,自定义原生广告格式也是使用 GADAdLoader
对象加载的。在初始化 GADAdLoader
时将 GADAdLoaderAdTypeCustomNative
常量添加到 adTypes
数组中,将会将其配置为在加载广告时请求自定义原生格式。
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 都显示在其名称旁边。点击其中一个名称即可前往详情页面,其中会显示与该格式的字段相关的信息:
您可以在此处添加、修改和移除个别字段。记下每项素材资源的名称。该名称是用于在展示自定义原生广告格式时获取每个素材资源的数据的键。
展示自定义原生广告格式
自定义原生广告格式与系统定义的广告格式不同,因为发布商可以自行定义构成广告的素材资源列表。因此,展示自定义原生广告的过程在以下几方面与展示系统定义的格式不同:
- 由于
GADCustomNativeAd
旨在处理您创建的任何自定义原生广告格式,因此它没有命名资源访问器。而是提供imageForKey:
和stringForKey:
等方法,这些方法会将字段的名称作为参数。 - 没有可与
GADCustomNativeAd
搭配使用的GADNativeAdView
等专用广告视图类。您可以随意使用对用户体验有益的任何视图。 - 由于没有专用的广告视图类,因此您无需注册用于展示广告素材资源的任何视图。
下面是一个能够显示简单的自定义原生广告的广告视图示例:
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"]; } ...
呈现 AdChoices 图标
为支持《数字服务法案 (DSA)》,在欧洲经济区 (EEA) 投放的预订广告必须带有 AdChoices 图标和指向 Google 的“关于此广告”页面的链接。实现自定义原生广告时,您负责呈现 AdChoices 图标。在呈现主要广告素材资源时,请务必采取措施来呈现 AdChoices 图标并为其设置点击监听器。
以下示例会呈现“广告选择”图标并配置适当的点击行为。
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
有一个类型为 GADNativeAdCustomClickHandler
的属性 customClickHandler
Swift
typealias GADNativeAdCustomClickHandler = (assetID: String) -> Void
Objective-C
typedef void (^GADNativeAdCustomClickHandler)(NSString *assetID);
这是一个代码块 (Objective-C) / 闭包 (Swift),接受 assetID
作为输入参数,用于标识被点击的素材资源。
当用户点击自定义原生广告时,SDK 可能会做出以下三种响应,并按以下顺序尝试:
- 在 Objective-C 中调用
customClickHandler
块,或在 Swift 中调用闭包(如果已设置)。 - 循环遍历广告的深层链接网址,并打开第一个可找到匹配应用的网址。
- 打开浏览器,然后前往广告的传统目标网址。
customClickHandler
属性在 Objective-C 中接受代码块,在 Swift 中接受闭包。如果您设置了块或闭包,SDK 将运行该块或闭包,而不会执行进一步操作。不过,如果您设置 null 值,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:
/21775744923/example/native
该广告资源配置为投放示例应用安装广告和内容广告,以及使用以下素材资源的自定义原生广告格式:
- 标题(文字)
- MainImage(图片)
- 字幕(文字)
原生回填广告
如需测试原生回填广告的行为,请使用以下 Ad Manager 广告单元:
/21775744923/example/native-backfill
它将投放包含 AdChoices 叠加层的示例应用安装广告和内容广告。
在实际投放前,请务必更新代码,使其引用您的实际广告单元 ID 和广告格式 ID!