Bidding Android iOS 快应用 SDK H5 SDK Media API 常见问题

自渲染

简介

基本信息

自渲染是对原有类型的优化和升级,使用自渲染的API,您可以为您的应用打造定制式体验。

权限等级:开放

适用场景:您可自行定义广告布局样式和展示场景

包含内容:使用自渲染 API拉取到的广告数据主要包含如下字段:

  1. 广告App图标(URL)
  2. 广告媒体图(URL)
  3. 广告标题
  4. 广告描述

除此之外,开发者还可以获取到广告类型,广告星级,广告价格等内容,详见自下文主要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 )imageViews placeholder:(UIImage )placeholder 绑定展示的图片视图, 一张大图传一个, 三小图传三个, 会自动把返回图片设置到传入的图片视图中

营销组件能力

接入营销组件能力分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。

接入代码示例

加载并显示自渲染广告

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]) {
        // @warning 调用方法之前请先判断[dataObject isAdValid]是否为YES,当为NO时调用不生效
        // @warning 需要注意的是 -[GDTUnifiedNativeAdView registerDataObject:clickableViews:]方法需要避免重复多次调用的情况
        // @warning 需要注意的是 -[GDTUnifiedNativeAdView registerDataObject:clickableViews:customClickableViews:]方法需要避免重复多次调用的情况
        // @warning 当广告不需要展示并且销毁的时候,需要调用 -[GDTUnifiedNativeAdView unregisterDataObject]方法,即registerDataObject方法需要与unregisterDataObject方法成对调用
        [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(是否为三小图广告)等

 文档反馈

腾讯公司 版权所有