Skip to main content

iOS 原生自渲染广告接入

加载广告并注册回调#

自渲染广告加载是通过调用 KLNUnifiedNativeAd 类的静态方法 loadWithRequest: completionHandler: 完成的。该方法需要两个参数,一是 KLNUnifiedNativeAdRequest 对象,二是加载成功或者失败的回调Block。

加载成功得到 KLNUnifiedNativeAd 实例数组后,对每个 KLNUnifiedNativeAd 实例可以注册 KLNUnifiedNativeAdDelegate 代理对象,KLNUnifiedNativeAdDelegate 协议会在广告素材加载成功或失败、广告曝光、广告点击时回调;你也可以给 KLNUnifiedNativeAd 实例的videoController属性设置代理,捕获视频广告播放相关的回调,目前支持视频静音、取消静音、开始/恢复播放、暂停播放、播放结束回调。

通过 KLNUnifiedNativeAd 实例,你可以获得自渲染广告相关的信息,比如广告渲染view、广告类型、APP图标URL、标题、描述、操作文案、游可赢广告标识图片;通过调用 registerWithClickableViews 注册可点击view,通过render来渲染广告,你也可以给广告设置静音等。

SDK提供两种方式渲染广告:

  • 使用 KLNUnifiedNativeAd 实例的adView属性调用render方法来渲染广告,包括图片和视频。

  • 从V2.2.0.276开始,可以使用 KLNUnifiedNativeAd 实例的adView属性调用render方法来渲染视频广告;可以通过KLNUnifiedNativeAd实例的imageUrl获取图片链接,然后渲染到自己的view上。

  • 从v2.4.1版本开始,可以通过设置autoDownloadPolicy参数值来管理视频在指定网络环境下自动下载策略;

自渲染广告请求参数类名参数参数说明
KLNUnifiedNativeAdRequestposId广告位置Id,初始化函数initWithPosId:必填参数
adCount请求广告个数。推荐请求1个,最多请求10个。不填默认为1。
注意:设置了adCount,后台可能不返回广告,也可能返回,最多返回adCount个广告。
autoDownloadPolicy视频素材下载策略:控制视频素材下载时机;
默认任意网络环境下自动下载视频
如希望仅WIFI环境下自动下载视频,则可在请求前设置对应的值:KLNVideoDownloadPolicyWifiOnly。

以下示例展示了如何在自己的VC中加载 KLNUnifiedNativeAd :

@interface KLNDemoUnifiedNativeViewController ()<UITableViewDelegate, UITableViewDataSource, KLNUnifiedNativeAdDelegate, UITextFieldDelegate, KLNAdVideoControllerDelegate>
@property (nonatomic, strong)UITableView *dataTableView;
@property (nonatomic, strong)NSMutableArray<KLNUnifiedNativeAd *> *adList;
@property (nonatomic, strong)UITextField *posIDTextField;
@property (nonatomic, strong)UILabel *adCountLabel;
@property (nonatomic, strong)UISlider *adCountSlider;
@property (nonatomic, strong)NSMutableArray<KLNUnifiedNativeAd *> *tempAdList;
@end
@implementation KLNDemoUnifiedNativeViewController
- (void)_initData{
KLNUnifiedNativeAdRequest *request = [[KLNUnifiedNativeAdRequest alloc] initWithPosId:self.posIDTextField.text];
request.adCount = self.adCountSlider.value;
__weak typeof(self)weakSelf = self;
[KLNUnifiedNativeAd loadWithRequest:request completionHandler:^(NSArray<KLNUnifiedNativeAd *> * _Nullable adList, NSError * _Nullable error) {
if (adList && adList.count > 0) {
weakSelf.adList = [adList mutableCopy];
for (KLNUnifiedNativeAd * ad in weakSelf.adList) {
ad.delegate = weakSelf;
ad.viewController = weakSelf;
}
[weakSelf.dataTableView reloadData];
}
}];
// // 如果要在广告素材加载成功显示广告,用下面这段代码
// [KLNUnifiedNativeAd loadWithRequest:request completionHandler:^(NSArray<KLNUnifiedNativeAd *> * _Nullable adList, NSError * _Nullable error) {
//
// if (adList && adList.count > 0) {
// for (KLNUnifiedNativeAd * ad in adList) {
// ad.delegate = weakSelf;
// ad.viewController = weakSelf;
// [weakSelf.tempAdList addObject:ad];
// }
// }
// }];
}
#pragma mark - KLNUnifiedNativeAdDelegate
- (void)kln_unifiedNativeAdDidLoad:(KLNUnifiedNativeAd *)ad didCompleteWithError:(NSError *)error {
KLNDemoLog(@"🌹自渲染广告素材加载完成 ad:%@ error:%@", ad, error);
// 如果需要监听自渲染视频广告的播放回调,请设置videoController.delegate
ad.videoController.delegate = self;
// 如果要在广告素材加载成功显示广告,用下面这段代码
// if (!error && ad && ![self.adList containsObject:ad]) {
// [self.adList addObject:ad];
// [self.dataTableView reloadData];
// }
//
// if (ad && [self.tempAdList containsObject:ad]) {
// [self.tempAdList removeObject:ad];
// }
}
- (void)kln_unifiedNativeAdWillExpose:(KLNUnifiedNativeAd *)ad{
KLNDemoLog(@"🌹自渲染广告曝光 ad:%@", ad);
}
- (void)kln_unifiedNativeAdDidClick:(KLNUnifiedNativeAd *)ad{
KLNDemoLog(@"🌹自渲染广告点击 ad:%@", ad);
}
#pragma mark - KLNAdVideoControllerDelegate
- (void)videoControllerDidMuteVideo:(KLNAdVideoController *)videoController {
KLNDemoLog(@"🌹自渲染广告视频静音");
}
- (void)videoControllerDidUnmuteVideo:(KLNAdVideoController *)videoController {
KLNDemoLog(@"🌹自渲染广告视频取消静音");
}
- (void)videoControllerDidPlayVideo:(KLNAdVideoController *)videoController {
KLNDemoLog(@"🌹自渲染广告视频开始/恢复播放");
}
- (void)videoControllerDidPauseVideo:(KLNAdVideoController *)videoController {
KLNDemoLog(@"🌹自渲染广告视频暂停播放");
}
- (void)videoControllerDidEndVideoPlayback:(KLNAdVideoController *)videoController {
KLNDemoLog(@"🌹自渲染广告视频播放结束");
}
@end

完整代码请参考Demo。

展示广告#

展示广告有两种方式:

  • loadWithRequest拿到广告信息KLNUnifiedNativeAd数组后直接刷新你的列表;

  • 在广告素材下载回调方法kln_unifiedNativeAdDidLoad:里面刷新你的列表。两种的区别是方式1渲染出广告view的时候素材可能还没下载完,这个时候广告view会转菊花。

代码片段如下:

- (void)_initData{
KLNUnifiedNativeAdRequest *request = [[KLNUnifiedNativeAdRequest alloc] initWithPosId:self.posIDTextField.text];
request.adCount = self.adCountSlider.value;
__weak typeof(self)weakSelf = self;
[KLNUnifiedNativeAd loadWithRequest:request completionHandler:^(NSArray<KLNUnifiedNativeAd *> * _Nullable adList, NSError * _Nullable error) {
if (adList && adList.count > 0) {
weakSelf.adList = [adList mutableCopy];
for (KLNUnifiedNativeAd * ad in weakSelf.adList) {
ad.delegate = weakSelf;
ad.viewController = weakSelf;
}
[weakSelf.dataTableView reloadData];
}
}];
// // 如果要在广告素材加载成功显示广告,用下面这段代码
// [KLNUnifiedNativeAd loadWithRequest:request completionHandler:^(NSArray<KLNUnifiedNativeAd *> * _Nullable adList, NSError * _Nullable error) {
//
// if (adList && adList.count > 0) {
// for (KLNUnifiedNativeAd * ad in adList) {
// ad.delegate = weakSelf;
// ad.viewController = weakSelf;
// [weakSelf.tempAdList addObject:ad];
// }
// }
// }];
}
#pragma mark - KLNUnifiedNativeAdDelegate
- (void)kln_unifiedNativeAdDidLoad:(KLNUnifiedNativeAd *)ad didCompleteWithError:(NSError *)error{
KLNDemoLog(@"🌹自渲染广告素材加载完成 ad:%@ error:%@", ad, error);
// 如果需要监听自渲染视频广告的播放回调,请设置videoController.delegate
ad.videoController.delegate = self;
// 如果要在广告素材加载成功显示广告,用下面这段代码
// if (!error && ad && ![self.adList containsObject:ad]) {
// [self.adList addObject:ad];
// [self.dataTableView reloadData];
// }
//
// if (ad && [self.tempAdList containsObject:ad]) {
// [self.tempAdList removeObject:ad];
// }
}
/*
使用KLNUnifiedNativeAd实例的adView属性调用render方法来渲染广告
包括图片和视频。
*/
- (void)refreshUIWithModel:(KLNUnifiedNativeAd *)model{
if (!model) {
return;
}
NSInteger adViewTag = 10000;
UIView *subView = (UIView *)[self.myContentView viewWithTag:adViewTag];
if ([subView superview]) {
[subView removeFromSuperview];
}
self.curAd = model;
model.adView.tag = adViewTag;
[self.myContentView addSubview:model.adView];
[self.curAd.adView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.myContentView);
make.right.equalTo(self.myContentView);
make.top.equalTo(self.myContentView);
CGFloat wid = UIScreen.mainScreen.bounds.size.width - 2 * kUnifiedNativeAdBaseCell_horGap;
CGFloat hei = [KLNUnifiedNativeAd calcHeiWithWidth:wid nativeAd:model];
make.height.mas_equalTo(hei);
}];
[self.myContentView sendSubviewToBack:self.curAd.adView];
[self.appIconImageView sd_setImageWithURL:[NSURL URLWithString:[model.appIconURL stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]] placeholderImage:nil options:SDWebImageRetryFailed];
self.adTitleLabel.text = model.title;
self.adDescLabel.text = model.desc;
[self.actionBtn setTitle:model.actionTitle forState:UIControlStateNormal];
self.adLogoImageView.image = model.adLogoImage;
if (model.adType == KLNUnifiedNativeAdTypeHorVideo) {
self.volumeBtn.hidden = NO;
}else{
self.volumeBtn.hidden = YES;
}
self.volumeBtn.selected = model.isMuted;
NSMutableArray *clickableViews = [NSMutableArray array];
[clickableViews addObject:self];
if (self.actionBtn) {
[clickableViews addObject:self.actionBtn];
}
[model unregisterClickableViews];
[model registerWithClickableViews:clickableViews adView:self];
[model render];
}
/*
从V2.2.0.276开始,通过KLNUnifiedNativeAd实例的imageUrl获取图片链接。
然后渲染到自己的view上
*/
- (void)refreshUIWithModel:(KLNUnifiedNativeAd *)model{
if (!model) {
return;
}
self.curAd = model;
[self.adImageView mas_updateConstraints:^(MASConstraintMaker *make) {
CGFloat wid = UIScreen.mainScreen.bounds.size.width - 2 * kCustomPicUnifiedNativeCell_horGap;
CGFloat hei = [KLNUnifiedNativeAd calcHeiWithWidth:wid nativeAd:model];
make.height.mas_equalTo(hei);
}];
[self.adImageView sd_setImageWithURL:[NSURL URLWithString:[model.imageUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]] placeholderImage:nil options:SDWebImageRetryFailed];
[self.appIconImageView sd_setImageWithURL:[NSURL URLWithString:[model.appIconURL stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]] placeholderImage:nil options:SDWebImageRetryFailed];
self.adTitleLabel.text = model.title;
self.adDescLabel.text = model.desc;
[self.actionBtn setTitle:model.actionTitle forState:UIControlStateNormal];
self.adLogoImageView.image = model.adLogoImage;
NSMutableArray *clickableViews = [NSMutableArray array];
[clickableViews addObject:self];
if (self.actionBtn) {
[clickableViews addObject:self.actionBtn];
}
[model unregisterClickableViews];
[model registerWithClickableViews:clickableViews adView:self];
}

完整代码请参考Demo。

主要API#

类名API方法API方法说明
KLNUnifiedNativeAddelegateKLNUnifiedNativeAdDelegate协议代理,会在广告素材加载成功或失败、广告曝光、广告点击时回调。
+loadWithRequest:
completionHandler:
加载自渲染广告入口,在回调block里返回广告实体对象数组,错误信息用NSError对象存储
videoController视频播放器
videoController的delegate属性设置代理,捕获视频广告播放相关的回调,目前支持视频静音、取消静音、开始/恢复播放、暂停播放、播放结束回调。
adView广告view。接入方拿到这个view后可以加入到自己的视图中显示广告。
registerWithClickableViews:参数clickableViews:
注册可点击的视图数组,此数组内的广告元素会添加手势,可以响应广告对应的点击事件。
从V2.2.0.276开始增加参数adView:
传入显示广告的view,SDK需要对此view做曝光检测。
升级到V2.2.0.276及以后的版本请做好兼容。
从V2.4.0开始,点击视频广告,会跳转视频详情页。
unregisterClickableViews解除注册可点击的视图数组。
render渲染广告View。接入方拿到adView属性后,需要调用render方法才能渲染广告。
只有接入方用KLNUnifiedNativeAd的属性adView进行广告渲染才调用此方法。否则不需要调用。
calcHeiWithWidth:nativeAd:接入方传入宽度,计算adview的高度。
dislike用户手动关闭广告时,请调用该方法。
调用该方法有助于游可赢帮你改善广告推荐。
title标题
desc描述
appIconURLApp图标URL
actionTitle按钮文案
adLogoImage游可赢广告标识图片
muted静音视频广告
adTypeKLNUnifiedNativeAdType枚举。
1001代表自渲染-横版大图16:9
1002代表自渲染-横版视频16:9
1003代表自渲染-竖版大图9:16(从V2.9.0版本开始新增样式)
1004代表自渲染-竖版视频9:16(从2.9.0版本开始新增样式)
viewController开发者传入的用来present目标页的ViewController
width广告宽度
height广告高度
imageUrl广告图片URL
V2.2.0.276新增属性
videoAutoPlayPolicyV2.2.0.286新增属性。
视频广告自动播放策略。默认 KLNUnifiedNativeAdVideoAutoPlayPolicyAlways(总是自动播放)。
KLNUnifiedNativeAdVideoAutoPlayPolicy类型枚举:
KLNUnifiedNativeAdVideoAutoPlayPolicyAlways // 总是自动播放,无论网络条件
KLNUnifiedNativeAdVideoAutoPlayPolicyWIFI // WIFI 下自动播放
KLNUnifiedNativeAdVideoAutoPlayPolicyNever // 从不自动播放,无论网络条件
kln_unifiedNativeAdDidCloseOtherController:interactionType:广告跳转到其他控制器时,控制器被关闭时调用。
interactionType参数:KLNInteractionType枚举类型,包括Appstore/网页/视频详情页等。
请注意:从V2.8.0版本开始支持该方法回调。
promotedType返回广告的推广类型:2=下载广告; 3=网页推广广告【2.10.1版本新增】
requestId广告请求ID
请注意:从V2.11版本新增该字段,接入方可以拼接requestId和creativeID唯一标记一个广告
creativeID广告创意ID
请注意:从V2.11版本新增该字段,接入方可以拼接requestId和creativeID唯一标记一个广告

其他说明#

  1. 广告曝光kln_unifiedNativeAdWillExpose:方法回调的时机需满足以下条件:广告view可见,alpha不小于0.9,曝光面积不小于50%,广告view宽度不小于屏幕宽度三分之一(从V2.3.0.220开始该判断条件去掉)持续曝光1s(从V2.6.1开始该判断条件去掉)。对于一个广告,只会执行曝光回调一次。

  2. V2.9.0版本开始,原生自渲染广告支持竖版素材,新增9:16大图和9:16视频样式。开发者可以通过KLNUnifiedNativeAd的adType属性获取到竖版样式(KLNUnifiedNativeAdTypeVerBigImage代表9:16大图,KLNUnifiedNativeAdTypeVerVideo代表9:16视频),从而进行定制化开发。