自渲染
简介
基本信息
自渲染是对原有类型的优化和升级,使用自渲染的API,您可以为您的应用打造定制式体验。
权限等级:开放
适用场景:您可自行定义广告布局样式和展示场景
包含内容:使用自渲染 API拉取到的广告数据主要包含如下字段:
- 广告App图标(URL)
- 广告媒体图(URL)
- 广告标题
- 广告描述
除此之外,开发者还可以获取到广告类型,广告星级,广告价格等内容,详见自下文主要API介绍
主要API
GDTUnifiedNativeAd 事件回调
@protocol GDTUnifiedNativeAdDelegate <NSObject>
/**
广告数据回调
@param unifiedNativeAdDataObjects 广告数据数组
@param error 错误信息
*/
- (void)gdt_unifiedNativeAdLoaded:(NSArray<GDTUnifiedNativeAdDataObject *> * _Nullable)unifiedNativeAdDataObjects error:(NSError * _Nullable)error;
@end
GDTUnifiedNativeAdView 事件回调
@protocol GDTUnifiedNativeAdViewDelegate <NSObject>
@optional
/**
广告曝光回调
@param unifiedNativeAdView GDTUnifiedNativeAdView 实例
*/
- (void)gdt_unifiedNativeAdViewWillExpose:(GDTUnifiedNativeAdView *)unifiedNativeAdView;
/**
广告点击回调
@param unifiedNativeAdView GDTUnifiedNativeAdView 实例
*/
- (void)gdt_unifiedNativeAdViewDidClick:(GDTUnifiedNativeAdView *)unifiedNativeAdView;
/**
广告详情页关闭回调
@param unifiedNativeAdView GDTUnifiedNativeAdView 实例
*/
- (void)gdt_unifiedNativeAdDetailViewClosed:(GDTUnifiedNativeAdView *)unifiedNativeAdView;
/**
当点击应用下载或者广告调用系统程序打开时调用
@param unifiedNativeAdView GDTUnifiedNativeAdView 实例
*/
- (void)gdt_unifiedNativeAdViewApplicationWillEnterBackground:(GDTUnifiedNativeAdView *)unifiedNativeAdView;
/**
广告详情页面即将展示回调
@param unifiedNativeAdView GDTUnifiedNativeAdView 实例
*/
- (void)gdt_unifiedNativeAdDetailViewWillPresentScreen:(GDTUnifiedNativeAdView *)unifiedNativeAdView;
/**
视频广告播放状态更改回调
@param nativeExpressAdView GDTUnifiedNativeAdView 实例
@param status 视频广告播放状态
@param userInfo 视频广告信息
*/
- (void)gdt_unifiedNativeAdView:(GDTUnifiedNativeAdView *)unifiedNativeAdView playerStatusChanged:(GDTMediaPlayerStatus)status userInfo:(NSDictionary *)userInfo;
@end
视频控件GDTMediaView回调
@protocol GDTMediaViewDelegate <NSObject>
@optional
/**
用户点击 MediaView 回调,当 GDTVideoConfig userControlEnable 设为 YES,用户点击 mediaView 会回调。
@param mediaView 播放器实例
*/
- (void)gdt_mediaViewDidTapped:(GDTMediaView *)mediaView;
/**
播放完成或者错误回调
@param mediaView 播放器实例
*/
- (void)gdt_mediaViewDidPlayFinished:(GDTMediaView *)mediaView;
@end
在实现上述事件回调之前,请务必先设置delegate:
Objective-C
self.unifiedNativeAd.delegate = self;//设置GDTUnifiedNativeAd的代理
unifiedNativeAdView.delegate = self;//设置GDTUnifiedNativeAdView的代理
unifiedNativeAdView.mediaView.delegate = self;//设置GDTMediaView的代理
Swift
self.nativeAdCustomView!.mediaView.delegate = self
self.unifiedNativeAd?.delegate = self
self.nativeAdView.delegate = self
GDTUnifiedNativeAdDataObject 广告信息数据对象
方法名 | 方法介绍 |
---|---|
- (BOOL)equalsAdData:(GDTUnifiedNativeAdDataObject *)dataObject | 判断两个自渲染2.0广告数据是否相等 |
- (void)bindImageViews:(NSArray |
绑定展示的图片视图, 一张大图传一个, 三小图传三个, 会自动把返回图片设置到传入的图片视图中 |
营销组件能力
接入营销组件能力分2步:
step1:判断广告是否支持营销组件能力
可通过GDTUnifiedNativeAdDataObject的callToAction属性来判断广告是否支持营销组件能力,返回为空值时表示该广告不支持营销组件能力,返回非空时,表示广告拥有营销组件能力,返回值代表SDK推荐开发者使用的文案,如“立即预约”、“电话咨询”等。
@interface GDTUnifiedNativeAdDataObject : NSObject
@property (nonatomic, readonly) NSString *callToAction;
@end
step2:接入营销组件能力
在step1中若广告支持营销组件能力,则调用GDTUnifiedNativeAdView的registerClickableCallToActionView方法注册点击事件,当发生点击行为时,系统会弹出营销组件页面,接口如下
@interface GDTUnifiedNativeAdView : UIView
/**
注册可点击的callToAction视图的方法
建议开发者使用GDTUnifiedNativeAdDataObject中的callToAction字段来创建视图,并取代自定义的下载或打开等button,
调用此方法之前必须先调用registerDataObject:clickableViews
@param callToActionView CTA视图, 系统自动处理点击事件
*/
- (void)registerClickableCallToActionView:(UIView *)callToActionView;
@end
示例代码
self.titleLabel.text = unifiedNativeDataObject.title;
self.descLabel.text = unifiedNativeDataObject.desc;
NSURL *iconURL = [NSURL URLWithString:unifiedNativeDataObject.iconUrl];
NSURL *imageURL = [NSURL URLWithString:unifiedNativeDataObject.imageUrl];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSData *iconData = [NSData dataWithContentsOfURL:iconURL];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
dispatch_async(dispatch_get_main_queue(), ^{
self.iconImageView.image = [UIImage imageWithData:iconData];
self.imageView.image = [UIImage imageWithData:imageData];
});
});
//step1:判断广告是否支持营销组件能力,若支持使用callToAction设置button文案
if ([unifiedNativeDataObject.callToAction length] > 0) {
[self.clickButton setHidden:YES];
[self.CTAButton setHidden:NO];
[self.CTAButton setTitle:unifiedNativeDataObject.callToAction forState:UIControlStateNormal];
}
else {
[self.clickButton setHidden:NO];
[self.CTAButton setHidden:YES];
if (unifiedNativeDataObject.isWechatCanvasAd) {
[self.clickButton setTitle:@"去微信看看" forState:UIControlStateNormal];
} else if (unifiedNativeDataObject.isAppAd) {
[self.clickButton setTitle:@"下载" forState:UIControlStateNormal];
} else {
[self.clickButton setTitle:@"打开" forState:UIControlStateNormal];
}
}
//step2:注册点击事件,注册之前需要判断广告是否有效
if ([[dataObject callToAction] length] > 0 && [dataObject isAdValid]) {
[self.adView registerClickableCallToActionView:self.adView.CTAButton];
}
多阶底价能力
接入多阶底价能力分2步:
step1:
找优量汇运营同学开通广告位的多阶底价权限并提供底价配置信息;
step2:
通过GDTUnifiedNativeAdDataObject类的eCPMLevel属性查看当前广告对应的底价层级。
/**
返回广告的eCPM等级
@return 成功返回一个包含数字的string,比如@"2"表示底价等级为2,@""或nil表示无权限或后台异常
*/
@property (nonatomic, readonly) NSString *eCPMLevel;
实时竞价能力
接入实时竞价能力分2步:
step1:
找优量汇运营同学开通广告位的实时竞价权限;
step2:
当广告拉取成功后,通过GDTUnifiedNativeAdDataObject类的eCPM属性获取本条广告实时的eCPM价格,单位是分。
/**
返回广告的eCPM,单位:分
@return 成功返回一个大于等于0的值,-1表示无权限或后台出现异常
*/
- (NSInteger)eCPM;
说明:
当无权限调用该接口时,SDK会返回错误码-1。
接入代码示例
加载并显示自渲染广告
- SDK Demo 工程提供了各种场景的渲染示例,更具体的调用方法请参考 Demo。
1.在控制器头文件中加入SDK头文件,声明unifiedNativeAd变量和unifiedNativeAdView变量和nativeAD对应的data对象GDTNativeAdData
Objective-C
#import "GDTUnifiedNativeAd.h"
#import "GDTUnifiedNativeAdView.h"
@property (nonatomic, strong) GDTUnifiedNativeAd *unifiedNativeAd;
@property (nonatomic, strong) NSArray *dataArray;
Swift
private var unifiedNativeAd:GDTUnifiedNativeAd?
private var adDataArray:Array<Any> = []
2.在ViewController的实现文件中初始化并加载广告数据:
Objective-C
- (void)loadLogic
{
self.unifiedNativeAd = [[GDTUnifiedNativeAd alloc] initWithPlacementId:YOUR_PLACEMENT_ID];
self.unifiedNativeAd.delegate = self;
self.unifiedNativeAd.maxVideoDuration = (NSInteger)self.maxVideoDurationSlider.value; // 如果需要设置视频最大时长,可以通过这个参数来进行设置
[self.unifiedNativeAd loadAd];
}
Swift
override func viewDidLoad() {
super.viewDidLoad()
self.unifiedNativeAd = GDTUnifiedNativeAd.init(placementId: self.placementId)
self.unifiedNativeAd?.delegate = self
self.unifiedNativeAd?.maxVideoDuration = self.maxVideoDuration
self.unifiedNativeAd?.loadAd(withAdCount: 10)
}
3.将YOUR_PLACEMENT_ID替换成你自己的PLACEMENTID。
4.需要在广告内容准备就绪的时候展示广告。开发者需要在拿到数据的回调方法,即gdt_unifiedNativeAdLoaded:error里处理数据并做广告展示:
Objective-C
-(void)nativeAdSuccessToLoad:(NSArray *)nativeAdDataArray
{
/*广告数据拉取成功,存储并展示*/
if (unifiedNativeAdDataObjects) {
NSLog(@"成功请求到广告数据");
GDTUnifiedNativeAdDataObject *dataObject = unifiedNativeAdDataObjects[0];
if (dataObject.isVideoAd) {//这里以展示视频
[self setupVideoAdRelatedViews:dataObject];
}
}
}
- (void)setupVideoAdRelatedViews:(GDTUnifiedNativeAdDataObject *)dataObject
{
/*自渲染视图类*/
GDTUnifiedNativeAdView *unifiedNativeAdView = [[GDTUnifiedNativeAdView alloc] initWithFrame:CGRectMake(10, 250, self.view.frame.size.width - 2 * 10, 250)];
unifiedNativeAdView.delegate = self;
unifiedNativeAdView.viewController = self; // 设置点击跳转的 VC
...
//此处略去其它广告元素的创建,请开发者参考Demo或者自行创建
...
/*定义视频媒体视图*/
// 配置视频播放属性
self.videoConfig = [[GDTVideoConfig alloc] init];
self.videoConfig.videoMuted = NO;
self.videoConfig.autoPlayPolicy = GDTVideoAutoPlayPolicyAlways;
self.videoConfig.userControlEnable = YES;
self.videoConfig.autoResumeEnable = NO;
self.videoConfig.detailPageEnable = NO;
// 绑定广告数据与广告容器 View,绑定之前需要判断广告是否有效,否则会影响计费
if ([dataObject isAdValid]) {
[unifiedNativeAdView registerDataObject:dataObject clickableViews:@[mediaView]];
[self.view addSubview:unifiedNativeAdView];
}
}
Swift
func gdt_unifiedNativeAdLoaded(_ unifiedNativeAdDataObjects: [GDTUnifiedNativeAdDataObject]?, error: Error?){
/*广告数据拉取成功,存储并展示*/
if unifiedNativeAdDataObjects != nil {
print("成功请求到广告数据")
self.adDataArray = unifiedNativeAdDataObjects!
self.tableView!.reloadData()
}
}
/*在UnifiedNativeAdViewController里面配置自渲染视图类*/
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let vcType = demoArray[indexPath.row]
let vc:UnifiedNativeAdBaseViewController?
switch vcType {
case "图片Feed":
vc = UnifiedNativeAdFeedImageViewController()
case "视频Feed":
vc = UnifiedNativeAdFeedVideoTableViewController()
case "竖版全屏视频":
vc = UnifiedNativeAdPortraitVideoViewController()
case "竖版Feed视频":
vc = UnifiedNativeAdPortraitFeedViewController()
case "视频贴片广告":
vc = UnifiedNativePreVideoViewController()
default:
vc = nil
}
/*定义视频媒体视图*/
vc?.placementId = (self.placementTextField.text!.count > 0 ? self.placementTextField!.text:self.placementTextField!.placeholder)!
vc?.maxVideoDuration = Int(self.maxVideoDurationSlider.value)
//配置视频播放属性
let videoConfig:GDTVideoConfig = GDTVideoConfig()
videoConfig.videoMuted = self.shouldMuteOnVideoSwitch.isOn;
videoConfig.detailPageEnable = self.videoDetailPageEnableSwitch.isOn;
videoConfig.autoResumeEnable = self.autoResumeEnableSwitch.isOn;
videoConfig.userControlEnable = self.userControlEnableSwitch.isOn;
videoConfig.progressViewEnable = self.progressViewEnableSwitch.isOn;
videoConfig.coverImageEnable = self.coverImageEnableSwitch.isOn;
vc?.videoConfig = videoConfig
//判断vc是否为竖版全屏视频,分两种转场方式
if vc is UnifiedNativeAdPortraitVideoViewController {
self.present(vc!, animated: true, completion: nil)
}else {
self.navigationController?.pushViewController(vc!, animated: true)
}
}
在不展示自渲染广告时执行调试
在您的ViewController里实现如下回调,处理自渲染加载失败的问题:
Objective-C
/**
* 拉取广告的回调,包含成功和失败情况
*/
#pragma mark - GDTUnifiedNativeAdDelegate
- (void)gdt_unifiedNativeAdLoaded:(NSArray<GDTUnifiedNativeAdDataObject *> *)unifiedNativeAdDataObjects error:(NSError *)error
{
...
if (error.code == 5004) {
NSLog(@"没匹配的广告,禁止重试,否则影响流量变现效果");
} else if (error.code == 5005) {
NSLog(@"流量控制导致没有广告,超过日限额,请明天再尝试");
} else if (error.code == 5009) {
NSLog(@"流量控制导致没有广告,超过小时限额");
} else if (error.code == 5006) {
NSLog(@"包名错误");
} else if (error.code == 5010) {
NSLog(@"广告样式校验失败");
} else if (error.code == 3001) {
NSLog(@"网络错误");
} else {
NSLog(@"ERROR: %@", error);
}
}
Swift
/**
* 拉取广告的回调,包含成功和失败情况
*/
func gdt_unifiedNativeAdLoaded(_ unifiedNativeAdDataObjects: [GDTUnifiedNativeAdDataObject]?, error: Error?) {
...
if error != nil {
let code = (error! as NSError).code
if code == 5004 {
print("没匹配的广告,禁止重试,否则影响流量变现效果");
} else if code == 5005 {
print("流量控制导致没有广告,超过日限额,请明天再尝试");
} else if code == 5009 {
print("流量控制导致没有广告,超过小时限额");
} else if code == 5006 {
print("包名错误");
} else if code == 5010 {
print("广告样式校验失败");
} else if code == 3001 {
print("网络错误");
} else {
print("\(String(describing: error))");
}
}
}
如果需要关注视频播放出错的情况,开发者需要实现gdt_unifiedNativeAdView:playerStatusChanged:userInfo回调方法,并在里面对Error的情况做相应观察与处理:
Objective-C
- (void)gdt_unifiedNativeAdView:(GDTUnifiedNativeAdView *)unifiedNativeAdView playerStatusChanged:(GDTMediaPlayerStatus)status userInfo:(NSDictionary *)userInfo
{
NSLog(@"视频广告状态变更");
switch (status) {
......
case GDTMediaPlayerStatusError:
NSLog(@"视频播放出错");
//开发者可以在这里添加逻辑
default:
break;
}
}
Swift
func gdt_unifiedNativeAdView(_ nativeExpressAdView: GDTUnifiedNativeAdView!, playerStatusChanged status: GDTMediaPlayerStatus, userInfo: [AnyHashable : Any]! = [:]) {
print("视频广告状态变更")
switch status {
case .initial:
print("视频初始化")
case .loading:
print("视频加载中")
case .started:
print("视频开始播放")
case .paused:
print("视频暂停")
case .stoped:
print("视频停止")
case .error:
print("视频播放出错")
default:
break
}
if userInfo != nil {
let videoDuration: CGFloat = userInfo?[kGDTUnifiedNativeAdKeyVideoDuration] as! CGFloat
print("视频广告长度为\(videoDuration)")
}
}
说明:
1.register方法中,会判断isAdValid是否为YES,当为NO时调用不生效,建议在调用之前判断
2.register方法中,clickableViews只接受在容器可视范围内的元素的点击(有效点击),如果不在容器内可见,即便注册到clickableViews中也不会响应广告的点击事件;
3.新的自渲染调整了 API,不需要再自行创建 GDTLogoView 和 GDTMediaView,调用 register 方法后自动生成,可通过容器 View 获取 mediaView 调整布局,支持 AutoLayout。
4.LogoView不需要添加到任何View中,系统默认会生成一个logoView。如果想要自定义,只需要赋值给GDTUnifiedNativeAdView的logoView属性即可。
5.可以通过GDTUnifiedNativeAdDataObject的属性判断广告类型,例如isVideo(是否为视频广告)、isAppAd(是否为应用类广告)、isThreeImgsAd(是否为三小图广告)等