自定义广告平台Adapter实现

简介

本文档将介绍在iOS端如何实现自定义广告平台Adapter,主要包括初始化、加载广告、展示广告以及各广告类型的响应事件回调处理。

支持广告类型

目前支持的广告类型有六种,如下所示:

核心流程实现

  1. 定义Adapter类名,包括配置Adapter以及各广告类型对应Adapter,并遵循相关协议;
  2. 在Cloooud开发者平台配置相关信息,详情参见平台部分文档;
  3. 实现协议方法完成初始化(含隐私合规)、广告加载、展示方法及回调,详见下方说明;

常见问题

  1. 自定义Adapter需要按照示例中相应方法含义调用,否则会影响收益;
  2. 及时更新协议版本号为Cloooud支持的最新版本,否则可能无法使用;
  3. 自定义Adapter广告load之前需要确保开发者实现了CloooudCustomConfigAdapter协议并初始化network成功,network版本号,Adapter版本号均不能为空,否则无法加载广告;
  4. 自定义Adapter广告load成功或者失败只能调用一次;
  5. 所有调用自定义adapter的方法均在主线程,请勿进行耗时操作;
  6. 自定义Adapter支持广告频次控制、广告间隔控制、AB测试、测试工具;
  7. 自定义Adapter不支持show时预加载、广告对象复用、Service bidding、多阶底价。支持Client bidding;
  8. 自定义Adapter广告对象的show、click等回调需要在load广告回调之后;
  9. Cloooud已经处理了Banner的轮播,自定义Banner需要禁用轮播。

初始化配置

协议内容

自定义Adapter必须要有配置类,在配置类中完成Adapter及对应network的信息采集,对应协议为CloooudCustomConfigAdapter,接口实现如下所示:

方法名 参数说明 返回值 说明 是否必要
- (CloooudCustomAdapterVersion *)basedOnCustomAdapterVersion - CloooudCustomAdapterVersion * 用于校验Adapter使用协议版本,开发者更新Adapter时需将该值更新为Cloooud提供的最新值,该值与Cloooud要求不匹配可能影响Adapter的使用。
- (void)initializeAdapterWithConfiguration:(CloooudSdkInitConfig *_Nullable)initConfig initConfig: 初始化配置,包括平台下发初始化配置及部分开发者传入配置 void 开发者需在该方法中完成Adapter的初始化及对应network的初始化
- (NSString *_Nonnull)adapterVersion - void 用于Cloooud获取Adapter的版本号
- (NSString *_Nonnull)networkSdkVersion - void 用于Cloooud获取network的版本号
- (void)didRequestAdPrivacyConfigUpdate:(NSDictionary *)config config: 隐私合规配置,字段详见CloooudPrivacyConfig.h文件 void 在媒体开发者更新隐私配置时触发,初始化方法调用前一定会触发一次

示例代码

@interface CloooudDemoCustomConfigAdapter : NSObject <CloooudCustomConfigAdapter>
​
@end
​
@implementation CloooudDemoCustomConfigAdapter
​
// 该自定义adapter是基于哪个版本实现的,填写编写时的最新值即可,Cloooud会根据该值进行兼容处理
​
- (CloooudCustomAdapterVersion *)basedOnCustomAdapterVersion {
​
return CloooudCustomAdapterVersion1_0;
​
}
​
// adn初始化方法
// @param initConfig 初始化配置,包括appid、appkey基本信息和部分用户传递配置
​
- (void)initializeAdapterWithConfiguration:(CloooudSdkInitConfig *_Nullable)initConfig {
​
// 初始化network
​
[BUAdSDKManager setAppID:initConfig.appID];
​
// 其他配置
​
[BUAdSDKManager setThemeStatus:[self _converToPangleThemeStatus:initConfig.themeStatus]];
​
}
​
// adapter的版本号
​
- (NSString *_Nonnull)adapterVersion {
​
return @"1.0.0";
​
}
​
// adn的版本号
​
- (NSString *_Nonnull)networkSdkVersion {
​
return [BUAdSDKManager SDKVersion];
​
}
​
// 隐私权限更新,用户更新隐私配置时触发,初始化方法调用前一定会触发一次
​
- (void)didRequestAdPrivacyConfigUpdate:(NSDictionary *)config {
​
[[BUAdSDKConfiguration configuration] setPrivacyProvider:self];
​
}
​
@end

原生广告(Native)

协议内容

自定义Native adapter中需要实现的协议为CloooudCustomNativeAdapter,接口实现如下所示:

方法名 参数说明 返回值 说明 是否必要
- (void)loadNativeAdWithSlotID:(NSString )slotID andSize:(CGSize)size imageSize:(CGSize)imageSize parameter:(NSDictionary )parameter slotID: network广告位ID;size: 广告展示尺寸 imageSize: 广告中图片的展示尺寸; parameter: 广告请求的参数信息,详见下方加载参数部分 void 实现自定义广告平台加载开屏广告的逻辑
- (void)renderForExpressAdView:(UIView *)expressAdView expressAdView: 模板广告的视图,即开发者通过广告加载成功回调Cloooud的模板广告视图对象 void 渲染广告,为模板广告时会回调该方法,需对广告进行渲染,如不需要,建议直接回调renderSuccess
- (void)setRootViewController:(UIViewController )viewController forExpressAdView:(UIView )expressAdView viewController: 广告点击事件跳转控制器; expressView: 模板广告的视图,即开发者通过广告加载成功回调Cloooud的模板广告视图对象 void 为模板广告设置控制器,媒体开发者调用-[CloooudNativeAdView setRootViewController:]时触发 模板广告: 是 / 非模板广告: 否
- (void)setRootViewController:(UIViewController *)viewController forNativeAd:(id)nativeAd viewController: 广告点击事件跳转控制器; nativeAd: 非模板广告的广告对象,即开发者通过广告加载成功回调Cloooud的非模板广告的originMediatedNativeAd void 为非模板广告设置控制器,媒体开发者调用-[CloooudNativeAdView setRootViewController:]时触发 模板广告: 否 / 非模板广告: 是
- (void)registerContainerView:(kindof UIView *)containerView andClickableViews:(NSArray<kindof UIView > )views forNativeAd:(id)nativeAd containerView: 非模板广告的Cloooud层级视图,即CloooudNativeAdView; views: 媒体请求注册为点击区域的视图集合; nativeAd: 非模板广告的广告对象,即开发者通过广告加载成功回调Cloooud的非模板广告的originMediatedNativeAd void 非模板广告注册容器和可点击区域 否(视network支持情况选择使用,避免影响广告点击行为)
(void)didReceiveBidResult:(CloooudMediaBidResult *)result result: 竞价结果模型 void 收到竞价结果信息时可能触发,是否触发由-[CloooudNativeAdsManager bidNotify]结果确定

广告加载

在Native广告的adapter中使用如下方法完成广告加载,其中parameter参数包括了本次广告加载的所有数据,支持的参数详见下方加载参数部分,更完整信息请查看CloooudAdLoadingParams文件。

- (void)loadNativeAdWithSlotID:(nonnull NSString *)slotID andSize:(CGSize)size imageSize:(CGSize)imageSize parameter:(nonnull NSDictionary *)parameter {

// 获取广告加载数量

NSInteger count = [parameter[CloooudAdLoadingParamNALoadAdCount] integerValue];

// 获取是否需要加载模板广告,非必要,视network支持而定

BOOL express = [parameter[CloooudAdLoadingParamExpressAdType] integerValue] == 1;

// 模拟广告加载耗时,开发者需在此调用network加载广告方法

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

if (express) {

// 模拟加载模板广告

NSMutableArray *list = [NSMutableArray arrayWithCapacity:count];

for (int i = 0; i < count; i++) {

CloooudDemoCustomExpressNativeView *view = [[CloooudDemoCustomExpressNativeView alloc] initWithSize:size andImageSize:imageSize];

__weak typeof(self) ws = self;

// 模拟广告点击事件

view.didClickAction = ^(CloooudDemoCustomExpressNativeView * _Nonnull view) {

__strong typeof(ws) self = ws;

[self.bridge nativeAd:self didClickWithMediatedNativeAd:view];

[self.bridge nativeAd:self willPresentFullScreenModalWithMediatedNativeAd:view];

};

// 模拟广告展示事件

view.didMoveToSuperViewCallback = ^(CloooudDemoCustomExpressNativeView * _Nonnull view) {

__strong typeof(ws) self = ws;

[self.bridge nativeAd:self didVisibleWithMediatedNativeAd:view];

};

// 模拟广告关闭事件

view.didClickCloseAction = ^(CloooudDemoCustomExpressNativeView * _Nonnull view) {

__strong typeof(ws) self = ws;

[self.bridge nativeAd:self didCloseWithExpressView:view closeReasons:@[]];

};

view.viewController = self.bridge.viewControllerForPresentingModalView;

[list addObject:view];

}

[self.bridge nativeAd:self didLoadWithExpressViews:[list copy] exts:@[]];

} else {

// 模拟加载非模板广告

NSMutableArray *list = [NSMutableArray arrayWithCapacity:count];

for (int i = 0; i < count; i++) {

CloooudDemoCustomNativeData *data = [CloooudDemoCustomNativeData randomDataWithImageSize:imageSize];

__weak typeof(self) ws = self;

// 模拟广告点击事件

data.didClickAction = ^(CloooudDemoCustomNativeData * _Nonnull data) {

__strong typeof(ws) self = ws;

[self.bridge nativeAd:self didClickWithMediatedNativeAd:data];

[self.bridge nativeAd:self willPresentFullScreenModalWithMediatedNativeAd:data];

};

data.viewController = self.bridge.viewControllerForPresentingModalView;

id<CloooudMediatedNativeAdData, CloooudMediatedNativeAdViewCreator> helper = [[CloooudDemoCustomNativeAdHelper alloc] initWithAdData:data];

// 构造需要返回Cloooud的非模板广告数据

CloooudMediatedNativeAd *ad = [[CloooudMediatedNativeAd alloc] init];

ad.originMediatedNativeAd = data;

ad.view = ({

CloooudDemoCustomNativeView *v = [[CloooudDemoCustomNativeView alloc] init];

v.didMoveToSuperViewCallback = ^(CloooudDemoCustomNativeView * _Nonnull view) {

__strong typeof(ws) self = ws;

[self.bridge nativeAd:self didVisibleWithMediatedNativeAd:data]; // 注意:使用原始广告数据

}; v;

});

ad.viewCreator = helper;

ad.data = helper;

[list addObject:ad];

}

[self.bridge nativeAd:self didLoadWithNativeAds:[list copy] exts:@[]];

}

});

}

加载参数

参数名 参数类型 参数含义
CloooudAdLoadingParamLinkID NSString 聚合广告请求ID
CloooudAdLoadingParamMediationRitID NSString 聚合广告位ID
CloooudAdLoadingParamMediaRitID NSString ADN广告位ID
CloooudAdLoadingParamMediaName NSString ADN广告位名称,平台配置名称
CloooudAdLoadingParamExpressAdType NSNumber/NSInteger 是否请求模板广告,1 express; 2 native; 3 express2.0(for gdt only)
CloooudAdLoadingParamExpressAdTypeInfos NSDictionary 是否请求模板广告的描述信息,仅为开发者提供说明,非请求参数
CloooudAdLoadingParamNAExpectImageSize NSValue/CGSize 期望广告图片尺寸
CloooudAdLoadingParamNAExpectSize NSValue/CGSize 期望广告尺寸
CloooudAdLoadingParamNAIsMute NSNumber/BOOL 是否是静音
CloooudAdLoadingParamNALoadAdCount NSNumber/NSInteger 加载广告数量
CloooudAdLoadingParamCustomJson NSString(JSON) 自定义Adapter扩展参数,平台配置
CloooudAdLoadingParamBiddingType NSNumber/NSInteger 获取竞价类型,平台配置,0-普通广告位 1-Client竞价广告位 100-P层数据位

回调协议

开发者需通过回调方式将广告加载/展示/交互情况通知到Cloooud,以保证流程的完整性。协议内容详见CloooudCustomNativeAdapterBridge.h

方法名 参数说明 返回值 说明 是否必要
- (void)nativeAd:(id_Nonnull)adapter didLoadWithNativeAds:(NSArray<CloooudMediatedNativeAd > _Nullable)ads exts:(NSArray<NSDictionary > _Nullable)exts adapter: 当前适配器;ads: 广告数据组,CloooudMediatedNativeAd创建方式见demo;exts: 需要回传的扩展数据,按照ads数组顺序匹配 void 在非模板广告加载完成时调用该方法 非模板广告: 是 模板广告: 否
- (void)nativeAd:(id_Nonnull)adapter didLoadFailWithError:(NSError *_Nullable)error adapter: 当前适配器 error: 广告加载出错的错误信息 void 在广告加载失败时调用该方法
- (void)nativeAd:(id_Nonnull)adapter didVisibleWithMediatedNativeAd:(id _Nonnull)nativeAd adapter: 当前适配器 nativeAd: 广告数据,native广告请传递原始数据(即CloooudMediatedNativeAd.originMediatedNativeAd),express广告请传递上报Cloooud的UIView void 收到广告展示回调时调用该方法
- (void)nativeAd:(id_Nonnull)adapter didClickWithMediatedNativeAd:(id _Nonnull)nativeAd adapter: 当前适配器 nativeAd: 广告数据,native广告请传递原始数据(即CloooudMediatedNativeAd.originMediatedNativeAd),express广告请传递上报Cloooud的UIView void 到广告点击事件回调时调用该方法
- (void)nativeAd:(id_Nonnull)adapter willPresentFullScreenModalWithMediatedNativeAd:(id _Nonnull)nativeAd adapter: 当前适配器 nativeAd: 广告数据,native广告请传递原始数据(即CloooudMediatedNativeAd.originMediatedNativeAd),express广告请传递上报Cloooud的UIView void 在广告即将展示详情页或者appstore时调用
- (void)nativeAd:(id_Nonnull)adapter willDismissFullScreenModalWithMediatedNativeAd:(id _Nonnull)nativeAd adapter: 当前适配器 nativeAd: 广告数据,native广告请传递原始数据(即CloooudMediatedNativeAd.originMediatedNativeAd),express广告请传递上报Cloooud的UIView void 在广告关闭详情页或者appstore时调用该方法
- (void)nativeAd:(id_Nonnull)adapter renderSuccessWithExpressView:(UIView *_Nonnull)expressView adapter: 当前适配器 expressView: 模板广告视图 void 在模板广告渲染成功或者模板广告的尺寸更新时调用,如network无需render,请主动回调该方法 模板广告: 是
- (void)nativeAd:(id_Nonnull)adapter renderFailWithExpressView:(UIView _Nonnull)expressView andError:(NSError _Nonnull)error adapter: 当前适配器 expressView: 模板广告视图 error: 渲染出错原因 void 在模板广告渲染失败调用 模板广告:是
- (void)nativeAd:(id_Nonnull)adapter didCloseWithExpressView:(UIView _Nonnull)expressView closeReasons:(NSArray<CloooudDemoislikeWords > *_Nullable)filterWords adapter: 当前适配器 expressView: 模板广告视图 filterWords: 用户手动广告关闭原因,可为nil void 在模板广告关闭的时候调用 模板广告:是
- (void)nativeAd:(id_Nonnull)adapter videoStateDidChangedWithState:(CloooudPlayerPlayState)state andNativeAd:(id _Nonnull)nativeAd adapter: 当前适配器 state: 广告中视频播放状态 nativeAd: 广告数据,native广告请传递原始数据(即CloooudMediatedNativeAd.originMediatedNativeAd),express广告请传递上报Cloooud的UIView void 视频广告中视频播放状态变更的时候调用
-(void)nativeAd:(id_Nonnull)adapter videoDidClick:(id _Nonnull)nativeAd adapter: 当前适配器 nativeAd: 广告数据,native广告请传递原始数据(即CloooudMediatedNativeAd.originMediatedNativeAd),express广告请传递上报Cloooud的UIView void 视频广告中视频视图被点击时调用
- (void)nativeAd:(id_Nonnull)adapter videoDidPlayFinish:(id _Nonnull)nativeAd adapter: 当前适配器 state: 广告中视频播放状态 nativeAd: 广告数据,native广告请传递原始数据(即CloooudMediatedNativeAd.originMediatedNativeAd),express广告请传递上报Cloooud的UIView void 视频广告中视频播放完成时调用

开屏广告(Splash)

协议内容

自定义Splash adapter中需要实现的协议为CloooudCustomSplashAdapter,接口实现如下所示:

方法名 参数说明 返回值 说明 是否必要
- (void)loadSplashAdWithSlotID:(NSString )slotID andParameter:(NSDictionary )parameter slotID: network广告位ID parameter: 广告请求的参数信息,详见下方加载参数部分 void 加载开屏广告
- (void)showSplashAdInWindow:(UIWindow )window parameter:(NSDictionary )parameter window: 广告展示页面 parameter: 预留参数 void 展示开屏广告
- (void)dismissSplashAd - void 广告关闭实现,在外部使用开发者调用destoryAd时触发
- (void)didReceiveBidResult:(CloooudMediaBidResult *)result result: 竞价结果模型 void 收到竞价结果信息时可能触发,是否触发由-[CloooudSplashAd bidNotify]结果决定

广告加载

在Splash广告的adapter中使用如下方法完成广告加载,其中parameter参数包括了本次广告加载的所有数据,支持的参数详见下方加载参数部分,更完整信息请查看CloooudAdLoadingParams文件。

@interface CloooudDemoCustomSplashAdapter () <CloooudCustomSplashAdapter>

@property (nonatomic, strong) CloooudDemoCustomSplashView *splashView;

@property (nonatomic, strong) UIView *customBottomView;

@end

@implementation CloooudDemoCustomSplashAdapter

- (CloooudMediatedAdStatus)mediatedAdStatus {

return CloooudMediatedAdStatusNormal;

}

- (void)dismissSplashAd {

[self.splashView removeFromSuperview];

[self.customBottomView removeFromSuperview];

}

- (void)loadSplashAdWithSlotID:(nonnull NSString *)slotID andParameter:(nonnull NSDictionary *)parameter {

CGSize size = [parameter[CloooudAdLoadingParamSPExpectSize] CGSizeValue];

self.customBottomView = parameter[CloooudAdLoadingParamSPCustomBottomView];

self.splashView = [CloooudDemoCustomSplashView splashViewWithSize:size rootViewController:self.bridge.viewControllerForPresentingModalView];

__weak typeof(self) ws = self;

// 模拟点击事件

self.splashView.didClickAction = ^(CloooudDemoCustomSplashView * _Nonnull view) {

__strong typeof(ws) self = ws;

[self.bridge splashAdDidClick:self];

};

// 模拟关闭事件

self.splashView.dismissCallback = ^(CloooudDemoCustomSplashView * _Nonnull view, BOOL skip) {

__strong typeof(ws) self = ws;

if (skip) {

[self.bridge splashAdDidClickSkip:self];

} else {

[self.bridge splashAdDidCountDownToZero:self];

}

[self.bridge splashAdDidClose:self];

};

// 模拟加载完成

[self.bridge splashAd:self didLoadWithExt:@{}];

}

加载参数

参数名 参数类型 参数含义
CloooudAdLoadingParamLinkID NSString 聚合广告请求ID
CloooudAdLoadingParamMediationRitID NSString 聚合广告位ID
CloooudAdLoadingParamMediaRitID NSString ADN广告位ID
CloooudAdLoadingParamMediaName NSString ADN广告位名称,平台配置名称
CloooudAdLoadingParamExpressAdType NSNumber/NSInteger 是否请求模板广告,1 express; 2 native; 3 express2.0(for gdt only)
CloooudAdLoadingParamExpressAdTypeInfos NSDictionary 是否请求模板广告的描述信息,仅为开发者提供说明,非请求参数
CloooudAdLoadingParamSPNeedZoomOutIfCan NSNumber/BOOL 是否期望ZoomOutView
CloooudAdLoadingParamSPCustomBottomView UIView 自定义底部视图
CloooudAdLoadingParamSPExpectSize NSValue/CGSize 期望广告尺寸
CloooudAdLoadingParamSPTolerateTimeout NSNumber/NSInteger 开屏超时时间
CloooudAdLoadingParamSPButtonType NSNumber/CloooudSplashButtonType 开屏点击区域
CloooudAdLoadingParamCustomJson NSString(JSON) 自定义Adapter扩展参数,平台配置
CloooudAdLoadingParamBiddingType NSNumber/NSInteger 获取竞价类型,平台配置,0-普通广告位 1-Client竞价广告位 100-P层数据位

广告展示

在Splash广告的adapter中使用如下方法完成广告展示,更完整信息请查看CloooudAdLoadingParams文件。

- (void)showSplashAdInWindow:(nonnull UIWindow *)window parameter:(nonnull NSDictionary *)parameter {

[self.splashView showInWindow:window];

if (self.customBottomView) {

[window addSubview:self.customBottomView];

}

// 模拟广告展示回调

[self.bridge splashAdWillVisible:self];

}

回调协议

开发者需通过回调方式将广告加载/展示/交互情况通知到Cloooud,以保证流程的完整性。协议内容详见CloooudCustomSplashAdapterBridge.h。zoomOut相关内容参见CloooudCustomSplashAdapterZoomOutViewBridge协议。

方法名 参数说明 返回值 说明 是否必要
(void)splashAd:(id_Nonnull)adapter didLoadWithExt:(NSDictionary *)ext adapter: 当前适配器 ext: 补充回传信息 void 在广告加载完成时调用该方法
- (void)splashAd:(id_Nonnull)adapter didLoadFailWithError:(NSError _Nullable)error ext:(NSDictionary )ext adapter: 当前适配器 error: 加载失败的错误信息 ext: 补充回传信息 void 在广告加载失败时调用该方法
- (void)splashAd:(id)adapter hasZoomOutView:(UIView )view withProperty:(void(^)(CloooudZoomOutViewProperty prop))property adapter: 当前适配器 view: zoom out view property: zoom out view的一些属性设定 void 在广告加载完成后如果存在zoomview时调用,应早于splashAd:didLoadWithExt:回调
- (void)splashAdWillVisible:(id_Nonnull)adapter adapter: 当前适配器 void 在广告即将展示时调用
- (void)splashAdDidShowFailed:(id)adapter error:(NSError *)error adapter: 当前适配器 error: 广告展示失败的错误信息 void 广告展示失败的时候调用该方法
- (void)splashAdDidClick:(id_Nonnull)adapter adapter: 当前适配器 void 在广告点击事件触发时调用
- (void)splashAdDidClose:(id_Nonnull)adapter adapter: 当前适配器 void 在广告关闭时调用
- (void)splashAdWillPresentFullScreenModal:(id_Nonnull)adapter adapter: 当前适配器 void 在广告即将展示详情页或者appstore时调用
- (void)splashAdWillDismissFullScreenModal:(id_Nonnull)adapter adapter: 当前适配器 void 在广告关闭详情页或者appstore时调用
- (void)splashAdDidRenderSuccess:(id_Nonnull)adapter adapter: 当前适配器 void 在模板广告渲染成功时调用
- (void)splashAd:(id_Nonnull)adapter didRenderFailedWithError:(NSError *)error adapter: 当前适配器 void 在广告渲染失败时调用
- (void)splashAdDidCountDownToZero:(id_Nonnull)adapter adapter: 当前适配器 void 在广告倒计时结束时调用

Banner广告

协议内容

自定义Banner adapter中需要实现的协议为CloooudCustomBannerAdapter,接口实现如下所示:

方法名 参数说明 返回值 说明 是否必要
- (void)loadBannerAdWithSlotID:(NSString )slotID andSize:(CGSize)adSize parameter:(nullable NSDictionary )parameter slotID: network广告位ID parameter: 广告请求的参数信息,详见下方加载参数部分 void 加载Banner广告
- (void)didReceiveBidResult:(CloooudMediaBidResult *)result result: 竞价结果模型 void 收到竞价结果信息时可能触发,是否触发由-[CloooudBanner bidNotify]结果确定

广告加载

在Banner广告的adapter中使用如下方法完成广告加载,其中parameter参数包括了本次广告加载的所有数据,支持的参数详见下方加载参数部分,更完整信息请查看CloooudAdLoadingParams文件。

@interface CloooudDemoCustomBannerAdapter () <CloooudCustomBannerAdapter>

@property (nonatomic, assign) NSTimeInterval lastLoadTimeInterval;

@end

@implementation CloooudDemoCustomBannerAdapter

- (CloooudMediatedAdStatus)mediatedAdStatus {
    CloooudMediatedAdStatus status = CloooudMediatedAdStatusNormal;
    if (self.lastLoadTimeInterval + 30.f > CACurrentMediaTime()) { // 模拟30秒,广告过期
        status.unexpired = CloooudMediatedAdStatusValueDeny;
    }
    return status;
}

- (void)loadBannerAdWithSlotID:(nonnull NSString *)slotID andSize:(CGSize)adSize parameter:(nullable NSDictionary *)parameter {
    // 混用代码位时,代码位类型
    self.adSubType = [parameter[CloooudAdLoadingParamAdSubType] integerValue];
    if (self.adSubType == 4) { // banner广告位下混用信息流代码位
        [self _mixNativeloadNativeAdWithSlotID:slotID andSize:adSize imageSize:[parameter[CloooudAdLoadingParamNAExpectImageSize] CGSizeValue] parameter:parameter];
    } else { // banner代码位
        if (CGSizeEqualToSize(adSize, CGSizeZero)) adSize = CGSizeMake(300, 200);
        // 模拟加载耗时
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            CGRect frame = (CGRect){CGPointZero, adSize};
            CloooudDemoCustomBannerView *bannerView = [[CloooudDemoCustomBannerView alloc] initWithFrame:frame];
            self.bannerView = bannerView;
            __weak typeof(self) ws = self;
            // 模拟展示回调
            bannerView.didMoveToSuperViewCallback = ^(CloooudDemoCustomBannerView *view) {
                __strong typeof(ws) self = ws;
                [self.bridge bannerAdDidBecomeVisible:self bannerView:view];
            };
            // 模拟关闭回调
            bannerView.closeAction = ^(CloooudDemoCustomBannerView *view) {
                __strong typeof(ws) self = ws;
                [self.bridge bannerAd:self bannerView:view didClosedWithDislikeWithReason:@[]];
            };
            // 模拟点击回调
            [bannerView addTarget:self action:@selector(didClick:) forControlEvents:UIControlEventTouchUpInside];
            // 模拟加载成功回调
            [self.bridge bannerAd:self didLoad:bannerView ext:@{
                // 模拟回调补充参数
                CloooudMediaAdLoadingExtECPM : @"[可选]更多字段参考CloooudAdLoadingParams.h"
            }];
            self.lastLoadTimeInterval = CACurrentMediaTime();
        });
    }

}
- (void)_mixNativeloadNativeAdWithSlotID:(nonnull NSString *)slotID andSize:(CGSize)size imageSize:(CGSize)imageSize parameter:(nonnull NSDictionary *)parameter {
    // 获取是否需要加载模板广告,非必要,视network支持而定
    NSInteger renderType = [parameter[CloooudAdLoadingParamExpressAdType] integerValue];
    // 模拟广告加载耗时,开发者需在此调用network加载广告方法
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        if (renderType == 1) { // 此处仅说明渲染类型可下发,开发者需根据实际定义情况编写
            // 模拟加载模板广告
            CloooudDemoCustomExpressNativeView *view = [[CloooudDemoCustomExpressNativeView alloc] initWithSize:size andImageSize:imageSize];
            self.expressNativeView = view;
            __weak typeof(self) ws = self;
            // 模拟广告点击事件
            view.didClickAction = ^(CloooudDemoCustomExpressNativeView * _Nonnull view) {
                __strong typeof(ws) self = ws;
                [self.bridge bannerAdDidClick:self bannerView:view];
                [self.bridge bannerAdWillPresentFullScreenModal:self bannerView:view];
            };
            // 模拟广告展示事件
            view.didMoveToSuperViewCallback = ^(CloooudDemoCustomExpressNativeView * _Nonnull view) {
                __strong typeof(ws) self = ws;
                [self.bridge bannerAdDidBecomeVisible:self bannerView:view];
            };
            // 模拟广告关闭事件
            view.didClickCloseAction = ^(CloooudDemoCustomExpressNativeView * _Nonnull view) {
                __strong typeof(ws) self = ws;
                [self.bridge bannerAd:self bannerView:view didClosedWithDislikeWithReason:@[]];
            };
            view.viewController = self.bridge.viewControllerForPresentingModalView;
            NSDictionary *ext = @{
                CloooudMediaAdLoadingExtECPM : @"1000",
            };
            view.viewController = self.bridge.viewControllerForPresentingModalView;

            [self.bridge bannerAd:self didLoad:view ext:ext];
        } else {
            // 模拟加载非模板广告
            CloooudDemoCustomNativeData *data = [CloooudDemoCustomNativeData randomDataWithImageSize:imageSize];
            self.customNativeData = data;
            __weak typeof(self) ws = self;
            // 模拟广告点击事件
            data.didClickAction = ^(CloooudDemoCustomNativeData * _Nonnull data) {
                __strong typeof(ws) self = ws;
                [self.bridge bannerAdDidClick:self bannerView:self.canvasView];
                [self.bridge bannerAdWillPresentFullScreenModal:self bannerView:self.canvasView];
            };
            data.viewController = self.bridge.viewControllerForPresentingModalView;
            id<CloooudMediatedNativeAdData, CloooudMediatedNativeAdViewCreator> helper = [[CloooudDemoCustomNativeAdHelper alloc] initWithAdData:data];
            // 构造需要返回Cloooud的非模板广告数据
            CloooudMediatedNativeAd *ad = [[CloooudMediatedNativeAd alloc] init];
            ad.originMediatedNativeAd = data;
            ad.view = ({
                CloooudDemoCustomNativeView *v = [[CloooudDemoCustomNativeView alloc] init];
                v.didMoveToSuperViewCallback = ^(CloooudDemoCustomNativeView * _Nonnull view) {
                    __strong typeof(ws) self = ws;
                    [self.bridge bannerAdDidBecomeVisible:self bannerView:self.canvasView];
                }; v;
            });
            ad.viewCreator = helper;
            ad.data = helper;
            NSDictionary *ext = @{
                CloooudMediaAdLoadingExtECPM : @"1000",
            };

            CloooudCanvasView *view = [[CloooudCanvasView alloc]initWithNativeAd:ad adapter:self];
            self.canvasView = view;

            [self.bridge bannerAd:self didLoad:self.canvasView ext:ext];
        }
    });
}
- (void)registerContainerView:(nonnull __kindof UIView *)containerView andClickableViews:(nonnull NSArray<__kindof UIView *> *)views forNativeAd:(nonnull id)nativeAd {
    if ([nativeAd isKindOfClass:[CloooudDemoCustomNativeData class]]) {
        CloooudDemoCustomNativeData *ad = (CloooudDemoCustomNativeData *)nativeAd;
        [ad registerClickableViews:views];
    }
}

- (void)didReceiveBidResult:(CloooudMediaBidResult *)result {
    // 在此处理Client Bidding的结果回调
}

- (void)didClick:(CloooudDemoCustomBannerView *)sender {
    [self.bridge bannerAdDidClick:self bannerView:sender];
    [self.bridge bannerAdWillPresentFullScreenModal:self bannerView:sender];
    CloooudDemoStoreViewController *vc = [[CloooudDemoStoreViewController alloc] init];
    [vc openAppStoreWithAppId:@"1142110895" fromViewController:self.bridge.viewControllerForPresentingModalView complete:^{
        [self.bridge bannerAdWillDismissFullScreenModal:self bannerView:sender];
    }];
}

@end

加载参数

参数名 参数类型 参数含义
CloooudAdLoadingParamLinkID NSString 聚合广告请求ID
CloooudAdLoadingParamMediationRitID NSString 聚合广告位ID
CloooudAdLoadingParamMediaRitID NSString ADN广告位ID
CloooudAdLoadingParamMediaName NSString ADN广告位名称,平台配置名称
CloooudAdLoadingParamExpressAdType NSNumber/NSInteger 是否请求模板广告,1 express; 2 native; 3 express2.0(for gdt only)
CloooudAdLoadingParamExpressAdTypeInfos NSDictionary 是否请求模板广告的描述信息,仅为开发者提供说明,非请求参数
CloooudAdLoadingParamBNExpectSize NSValue/CGSize 期望广告尺寸
CloooudAdLoadingParamCustomJson NSString(JSON) 自定义Adapter扩展参数,平台配置
CloooudAdLoadingParamBiddingType NSNumber/NSInteger 获取竞价类型,平台配置,0-普通广告位 1-Client竞价广告位 100-P层数据位

回调协议

开发者需通过回调方式将广告加载/展示/交互情况通知到Cloooud,以保证流程的完整性。协议内容详见CloooudCustomBannerAdapterBridge.h。

方法名 参数说明 返回值 说明 是否必要
(void)bannerAd:(id)adapter didLoad:(UIView )bannerView ext:(NSDictionary )ext adapter: 当前适配器 bannerView: Banner广告视图 ext: 补充回传信息 void 在广告加载完成时调用该方法
- (void)bannerAd:(id)adapter didLoadFailWithError:(NSError _Nullable)error ext:(NSDictionary )ext adapter: 当前适配器 error: 广告加载出错信息 ext: 补充回传信息 void 在广告加载失败时调用该方法
- (void)bannerAdDidBecomeVisible:(id)adapter bannerView:(UIView *)bannerView adapter: 当前适配器 bannerView: Banner广告视图 void 在广告已经展示的时候调用该方法
- (void)bannerAdWillPresentFullScreenModal:(id)adapter bannerView:(UIView *)bannerView adapter: 当前适配器 bannerView: Banner广告视图 void 在广告弹出详情页或者展示展示appstore时调用该方法
- (void)bannerAdWillDismissFullScreenModal:(id)adapter bannerView:(UIView *)bannerView adapter: 当前适配器 bannerView: Banner广告视图 void 在广告关闭详情页或者appstore时调用该方法
- (void)bannerAdDidClick:(id)adapter bannerView:(UIView *)bannerView adapter: 当前适配器 bannerView: Banner广告视图 void 在广告触发点击事件时调用该方法
- (void)bannerAd:(id)adapter bannerView:(UIView )bannerView didClosedWithDislikeWithReason:(NSArray<CloooudDemoislikeWords > *_Nullable)filterwords adapter: 当前适配器 bannerView: Banner广告视图 filterwords: 用户手动广告关闭原因,可为nil void 在广告关闭时调用该方法

激励视频广告(RewardedVideo)

协议内容

自定义激励视频广告 adapter中需要实现的协议为CloooudCustomRewardedVideoAdapter,接口实现如下所示:

方法名 参数说明 返回值 说明 是否必要
- (void)loadRewardedVideoAdWithSlotID:(NSString )slotID andParameter:(NSDictionary )parameter slotID: network广告位ID parameter: 广告请求的参数信息,详见下方加载参数部分 void 加载激励视频广告
- (BOOL)showAdFromRootViewController:(UIViewController _Nonnull)viewController parameter:(NSDictionary )parameter viewController: 展示广告的UIViewController parameter: 展示参数,预留 void 展示广告的方法
- (void)didReceiveBidResult:(CloooudMediaBidResult *)result result: 竞价结果模型 void 收到竞价结果信息时可能触发,是否触发由-[CloooudRewardedVideoAd bidNotify]结果确定

广告加载

在激励视频广告的adapter中使用如下方法完成广告加载,其中parameter参数包括了本次广告加载的所有数据,支持的参数详见下方加载参数部分,更完整信息请查看CloooudAdLoadingParams文件。

@interface CloooudDemoCustomRewardedVideoAdapter () <CloooudCustomRewardedVideoAdapter>

@property (nonatomic, strong) CloooudDemoCustomRewardedVideoView *view;

@property (nonatomic, weak) UIViewController *viewController;

@end

@implementation CloooudDemoCustomRewardedVideoAdapter

- (CloooudMediatedAdStatus)mediatedAdStatus {

return CloooudMediatedAdStatusNormal;

}

- (void)loadRewardedVideoAdWithSlotID:(nonnull NSString *)slotID andParameter:(nonnull NSDictionary *)parameter {

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

// 模拟加载广告成功

[self.bridge rewardedVideoAd:self

didLoadWithExt:@{}];

// 模拟广告视频资源加载成功,可选

[self.bridge rewardedVideoAdVideoDidLoad:self];

});

}

@end

加载参数

参数名 参数类型 参数含义
CloooudAdLoadingParamLinkID NSString 聚合广告请求ID
CloooudAdLoadingParamMediationRitID NSString 聚合广告位ID
CloooudAdLoadingParamMediaRitID NSString ADN广告位ID
CloooudAdLoadingParamMediaName NSString ADN广告位名称,平台配置名称
CloooudAdLoadingParamExpressAdType NSNumber/NSInteger 是否请求模板广告,1 express; 2 native; 3 express2.0(for gdt only)
CloooudAdLoadingParamExpressAdTypeInfos NSDictionary 是否请求模板广告的描述信息,仅为开发者提供说明,非请求参数
CloooudAdLoadingParamRVIsMute NSNumber/BOOL 是否是静音
CloooudAdLoadingParamRVUserID NSString 用户标识
CloooudAdLoadingParamRVRewardName NSString 奖励名称
CloooudAdLoadingParamRVRewardAmount NSNumber/NSInteger 奖励金额
CloooudAdLoadingParamRVExtra NSString 激励视频扩展信息
CloooudAdLoadingParamCustomJson NSString(JSON) 自定义Adapter扩展参数,平台配置
CloooudAdLoadingParamBiddingType NSNumber/NSInteger 获取竞价类型,平台配置,0-普通广告位 1-Client竞价广告位 100-P层数据位

广告展示

在激励视频广告的adapter中使用如下方法完成广告展示,更完整信息请查看CloooudAdLoadingParams文件。

- (BOOL)showAdFromRootViewController:(UIViewController * _Nonnull)viewController parameter:(nonnull NSDictionary *)parameter {

self.viewController = viewController;

self.view = [CloooudDemoCustomRewardedVideoView fullscreenView];

[self.view showInViewController:viewController];

__weak typeof(self) ws = self;

// 模拟广告关闭

self.view.dismissCallback = ^(CloooudDemoCustomRewardedVideoView * _Nonnull view, BOOL skip) {

__strong typeof(ws) self = ws;

if (!skip) {

// 模拟广告获取奖励

[self.bridge rewardedVideoAd:self didServerRewardSuccessWithInfo:^(CloooudAdapterRewardAdInfo * _Nonnull info) {

info.rewardName = @"[可选]";

info.rewardAmount = 1;

info.tradeId = @"[可选]";

info.verify = YES;

}];

}

[self.bridge rewardedVideoAdDidClose:self];

};

// 模拟点击跳过

self.view.skipCallback = ^(CloooudDemoCustomRewardedVideoView * _Nonnull view) {

__strong typeof(ws) self = ws;

[self.bridge rewardedVideoAdDidClickSkip:self];

};

// 模拟广告点击事件

[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didClick)]];

// 模拟广告展示

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

[self.bridge rewardedVideoAdDidVisible:self];

});

// 模拟广告播放完成

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

[self.bridge rewardedVideoAd:self didPlayFinishWithError:nil];

});

return YES;

}

- (void)didClick {

[self.bridge rewardedVideoAdDidClick:self];

[self.bridge rewardedVideoAdWillPresentFullScreenModel:self];

CloooudDemoStoreViewController *vc = [[CloooudDemoStoreViewController alloc] init];

[vc openAppStoreWithAppId:@"1142110895" fromViewController:self.viewController complete:^{

[self.bridge rewardedVideoAdWillDismissFullScreenModel:self];

}];

}

回调协议

开发者需通过回调方式将广告加载/展示/交互情况通知到Cloooud,以保证流程的完整性。协议内容详见CloooudCustomRewardedVideoAdapterBridge.h。

方法名 参数说明 返回值 说明 是否必要
- (void)rewardedVideoAd:(id_Nonnull)adapter didLoadWithExt:(NSDictionary *)ext adapter: 当前适配器 ext: 补充回传信息 void 在广告加载完成时调用该方法
- (void)rewardedVideoAd:(id_Nonnull)adapter didLoadFailWithError:(NSError _Nullable)error ext:(NSDictionary )ext adapter: 当前适配器 error: 广告加载失败的出错信息 ext: 补充回传信息 void 在广告加载失败时调用该方法
- (void)rewardedVideoAdVideoDidLoad:(id_Nonnull)adapter adapter: 当前适配器 void 在广告中视频素材加载完成时调用
- (void)rewardedVideoAdDidVisible:(id_Nonnull)adapter adapter: 当前适配器 void 在广告已经展示时调用
- (void)rewardedVideoAdDidShowFailed:(id)adapter error:(NSError *)error adapter: 当前适配器 error: 展示失败的出错原因 void 广告展示失败的时候调用该方法
- (void)rewardedVideoAdDidClose:(id_Nonnull)adapter adapter: 当前适配器 void 在广告关闭时调用
- (void)rewardedVideoAdDidClick:(id_Nonnull)adapter adapter: 当前适配器 void 在广告点击事件触发时调用
- (void)rewardedVideoAd:(id_Nonnull)adapter didPlayFinishWithError:(NSError *_Nullable)error adapter: 当前适配器 void 在广告视频播放完成时调用
- (void)rewardedVideoAd:(id_Nonnull)adapter didServerRewardSuccessWithInfo:(void(^)(CloooudAdapterRewardAdInfo *info))infoBuilder adapter: 当前适配器 infoBuilder: 激励信息构造block void 在network验证激励成功时调用
(void)rewardedVideoAdDidClickSkip:(id_Nonnull)adapter adapter: 当前适配器 void 在广告被点击跳过时调用
- (void)rewardedVideoAdRenderSuccess:(id_Nonnull)adapter adapter: 当前适配器 void 在模板广告渲染成功时调用,非模板广告无需调用 模板广告: 是
- (void)rewardedVideoAd:(id_Nonnull)adapter renderFailedWithError:(NSError *_Nullable)error adapter: 当前适配器 error: 渲染失败原因 void 在广告渲染失败时调用,非模板广告无需调用 模板广告: 是
- (void)rewardedVideoAdWillPresentFullScreenModel:(id_Nonnull)adapter adapter: 当前适配器 void 在广告即将展示详情页或者appstore时调用
- (void)rewardedVideoAdWillDismissFullScreenModel:(id_Nonnull)adapter adapter: 当前适配器 void 在广告关闭详情页或者app store时调用

全屏视频广告(FullscreenVideo)

协议内容

自定义全屏视频广告 adapter中需要实现的协议为CloooudCustomFullscreenVideoAdapter,接口实现如下所示:

方法名 参数说明 返回值 说明 是否必要
- (void)loadFullscreenVideoAdWithSlotID:(NSString )slotID andParameter:(NSDictionary )parameter slotID: network广告位ID parameter: 广告请求的参数信息,详见下方加载参数部分 void 加载全屏视频广告
- (BOOL)showAdFromRootViewController:(UIViewController _Nonnull)viewController parameter:(NSDictionary )parameter viewController: 展示广告的UIViewController parameter: 展示参数,预留 void 展示广告的方法
- (void)didReceiveBidResult:(CloooudMediaBidResult *)result result: 竞价结果模型 void 收到竞价结果信息时可能触发,是否触发由-[CloooudFullscreenVideoAd bidNotify]结果确定

广告加载

在全屏视频广告的adapter中使用如下方法完成广告加载,其中parameter参数包括了本次广告加载的所有数据,支持的参数详见下方加载参数部分,更完整信息请查看CloooudAdLoadingParams文件。

@interface CloooudDemoCustomFullscreenVideoAdapter () <CloooudCustomFullscreenVideoAdapter>

@property (nonatomic, strong) CloooudDemoCustomFullscreenView *view;

@property (nonatomic, weak) UIViewController *viewController;

@end

@implementation CloooudDemoCustomFullscreenVideoAdapter

- (CloooudMediatedAdStatus)mediatedAdStatus {

return CloooudMediatedAdStatusNormal;

}

- (void)loadFullscreenVideoAdWithSlotID:(nonnull NSString *)slotID andParameter:(nonnull NSDictionary *)parameter {

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

// 模拟广告加载成功回调

[self.bridge fullscreenVideoAd:self didLoadWithExt:@{}];

// 模拟广告视频加载完成回调

[self.bridge fullscreenVideoAdVideoDidLoad:self];

});

}

@end

加载参数

参数名 参数类型 参数含义
CloooudAdLoadingParamLinkID NSString 聚合广告请求ID
CloooudAdLoadingParamMediationRitID NSString 聚合广告位ID
CloooudAdLoadingParamMediaRitID NSString ADN广告位ID
CloooudAdLoadingParamMediaName NSString ADN广告位名称,平台配置名称
CloooudAdLoadingParamExpressAdType NSNumber/NSInteger 是否请求模板广告,1 express; 2 native; 3 express2.0(for gdt only)
CloooudAdLoadingParamExpressAdTypeInfos NSDictionary 是否请求模板广告的描述信息,仅为开发者提供说明,非请求参数
CloooudAdLoadingParamFVIsMute NSNumber/BOOL 是否是静音
CloooudAdLoadingParamCustomJson NSString(JSON) 自定义Adapter扩展参数,平台配置
CloooudAdLoadingParamBiddingType NSNumber/NSInteger 获取竞价类型,平台配置,0-普通广告位 1-Client竞价广告位 100-P层数据位

广告展示

- (BOOL)showAdFromRootViewController:(UIViewController * _Nonnull)viewController parameter:(nonnull NSDictionary *)parameter {

self.viewController = viewController;

self.view = [CloooudDemoCustomFullscreenView fullscreenView];

[self.view showInViewController:viewController];

__weak typeof(self) ws = self;

// 模拟广告关闭事件

self.view.dismissCallback = ^(CloooudDemoCustomFullscreenView * _Nonnull view) {

__strong typeof(ws) self = ws;

[self.bridge fullscreenVideoAdDidClose:self];

};

// 模拟广告点击跳过事件

self.view.skipCallback = ^(CloooudDemoCustomFullscreenView * _Nonnull view) {

__strong typeof(ws) self = ws;

[self.bridge fullscreenVideoAdDidClickSkip:self];

};

// 模拟广告点击事件

[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didClick)]];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

[self.bridge fullscreenVideoAdDidVisible:self];

});

// 模拟广告视频播放完成事件

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

[self.bridge fullscreenVideoAd:self didPlayFinishWithError:nil];

});

return YES;

}

- (void)didClick {

[self.bridge fullscreenVideoAdDidClick:self];

[self.bridge fullscreenVideoAdWillPresentFullscreenModal:self];

CloooudDemoStoreViewController *vc = [[CloooudDemoStoreViewController alloc] init];

[vc openAppStoreWithAppId:@"1142110895" fromViewController:self.viewController complete:^{}];

}

回调协议

开发者需通过回调方式将广告加载/展示/交互情况通知到Cloooud,以保证流程的完整性。协议内容详见CloooudCustomFullscreenVideoAdapterBridge.h。

方法名 参数说明 返回值 说明 是否必要
- (void)fullscreenVideoAd:(id_Nonnull)adapter didLoadWithExt:(NSDictionary *)ext adapter: 当前适配器 ext: 补充回传信息 void 在广告加载完成时调用该方法
- (void)fullscreenVideoAd:(id_Nonnull)adapter didLoadFailWithError:(NSError _Nullable)error ext:(NSDictionary )ext adapter: 当前适配器 error: 广告加载失败的出错信息 ext: 补充回传信息 void 在广告加载失败时调用该方法
- (void)fullscreenVideoAdVideoDidLoad:(id_Nonnull)adapter adapter: 当前适配器 void 在广告中视频素材加载完成时调用
- (void)fullscreenVideoAdDidVisible:(id_Nonnull)adapter adapter: 当前适配器 void 在广告已经展示时调用
- (void)fullscreenVideoAdDidShowFailed:(id)adapter error:(NSError *)error adapter: 当前适配器 error: 展示失败的出错原因 void 广告展示失败的时候调用该方法
- (void)fullscreenVideoAdDidClose:(id_Nonnull)adapter adapter: 当前适配器 void 在广告关闭时调用
- (void)fullscreenVideoAdDidClick:(id_Nonnull)adapter adapter: 当前适配器 void 在广告点击事件触发时调用
- (void)fullscreenVideoAd:(id_Nonnull)adapter didPlayFinishWithError:(NSError *_Nullable)error adapter: 当前适配器 void 在广告视频播放完成时调用
- (void)fullscreenVideoAdDidClickSkip:(id_Nonnull)adapter adapter: 当前适配器 void 在广告被点击跳过时调用
- (void)fullscreenVideoAdRenderSuccess:(id_Nonnull)adapter adapter: 当前适配器 void 在模板广告渲染成功时调用,非模板广告无需调用 模板广告: 是
- (void)fullscreenVideoAd:(id_Nonnull)adapter renderFailedWithError:(NSError *_Nullable)error adapter: 当前适配器 error: 渲染失败原因 void 在广告渲染失败时调用,非模板广告无需调用 模板广告: 是
- (void)fullscreenVideoAdWillPresentFullscreenModal:(id_Nonnull)adapter adapter: 当前适配器 void 在广告即将展示详情页或者app store时调用

插屏广告(Intersitial)

协议内容

自定义全屏视频广告 adapter中需要实现的协议为CloooudCustomInterstitialAdapter,接口实现如下所示:

方法名 参数说明 返回值 说明 是否必要
- (void)loadInterstitialAdWithSlotID:(NSString )slotID andSize:(CGSize)size parameter:(NSDictionary )parameter slotID: network广告位ID size: 期望广告展示的尺寸 parameter: 广告请求的参数信息,详见下方加载参数部分 void 加载全屏视频广告
- (BOOL)showAdFromRootViewController:(UIViewController _Nonnull)viewController parameter:(NSDictionary )parameter viewController: 展示广告的UIViewController parameter: 展示参数,预留 void 展示广告的方法
- (void)didReceiveBidResult:(CloooudMediaBidResult *)result result: 竞价结果模型 void 收到竞价结果信息时可能触发,是否触发由-[CloooudSplashAd bidNotify]结果确定

广告加载

在插屏广告的adapter中使用如下方法完成广告加载,其中parameter参数包括了本次广告加载的所有数据,支持的参数详见下方加载参数部分,更完整信息请查看CloooudAdLoadingParams文件。

@interface CloooudDemoCustomInterstitialAdapter () <CloooudCustomInterstitialAdapter>

@property (nonatomic, strong) CloooudDemoCustomInterstitialView *view;

@property (nonatomic, weak) UIViewController *viewController;

@property (nonatomic, assign) CGSize size;

@end

@implementation CloooudDemoCustomInterstitialAdapter

- (CloooudMediatedAdStatus)mediatedAdStatus {

return CloooudMediatedAdStatusNormal;

}

- (void)loadInterstitialAdWithSlotID:(NSString *)slotID andSize:(CGSize)size parameter:(NSDictionary *)parameter {

self.size = size;

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

// 模拟广告加载成功回调

[self.bridge interstitialAd:self didLoadWithExt:@{}];

});

}

@end

加载参数

参数名 参数类型 参数含义
CloooudAdLoadingParamLinkID NSString 聚合广告请求ID
CloooudAdLoadingParamMediationRitID NSString 聚合广告位ID
CloooudAdLoadingParamMediaRitID NSString ADN广告位ID
CloooudAdLoadingParamMediaName NSString ADN广告位名称,平台配置名称
CloooudAdLoadingParamExpressAdType NSNumber/NSInteger 是否请求模板广告,1 express; 2 native; 3 express2.0(for gdt only)
CloooudAdLoadingParamExpressAdTypeInfos NSDictionary 是否请求模板广告的描述信息,仅为开发者提供说明,非请求参数
CloooudAdLoadingParamISExpectSize NSValue/CGSize 期望展示尺寸
CloooudAdLoadingParamCustomJson NSString(JSON) 自定义Adapter扩展参数,平台配置
CloooudAdLoadingParamBiddingType NSNumber/NSInteger 获取竞价类型,平台配置,0-普通广告位 1-Client竞价广告位 100-P层数据位

广告展示

- (BOOL)showAdFromRootViewController:(UIViewController *)viewController parameter:(NSDictionary *)parameter {

self.viewController = viewController;

self.view = [CloooudDemoCustomInterstitialView interstitialViewWithSize:self.size];

[self.view showInViewController:viewController];

__weak typeof(self) ws = self;

// 模拟广告关闭事件

self.view.closeCallback = ^(CloooudDemoCustomInterstitialView * _Nonnull view) {

__strong typeof(ws) self = ws;

[self.bridge interstitialAdDidClose:self];

};

// 模拟广告点击事件

[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didClick)]];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

[self.bridge interstitialAdDidVisible:self];

});

return YES;

}

- (void)didClick {

[self.bridge interstitialAdDidClick:self];

[self.bridge interstitialAdWillPresentFullScreenModal:self];

CloooudDemoStoreViewController *vc = [[CloooudDemoStoreViewController alloc] init];

[vc openAppStoreWithAppId:@"1142110895" fromViewController:self.viewController complete:^{}];

}

回调协议

开发者需通过回调方式将广告加载/展示/交互情况通知到Cloooud,以保证流程的完整性。协议内容详见CloooudCustomInterstitialAdapterBridge.h。

方法名 参数说明 返回值 说明 是否必要
- (void)interstitialAd:(id_Nonnull)adapter didLoadWithExt:(NSDictionary *)ext adapter: 当前适配器 ext: 补充回传信息 void 在广告加载完成时调用该方法
- (void)interstitialAd:(id_Nonnull)adapter didLoadFailWithError:(NSError _Nullable)error ext:(NSDictionary )ext adapter: 当前适配器 error: 广告加载失败的出错信息 ext: 补充回传信息 void 在广告加载失败时调用该方法
- (void)interstitialAdDidVisible:(id_Nonnull)adapter adapter: 当前适配器 void 在广告已经展示时调用
- (void)interstitialAdDidShowFailed:(id)adapter error:(NSError *)error adapter: 当前适配器 error: 展示失败的出错原因 void 广告展示失败的时候调用该方法
- (void)interstitialAdDidClose:(id_Nonnull)adapter adapter: 当前适配器 void 在广告关闭时调用
- (void)interstitialAdDidClick:(id_Nonnull)adapter adapter: 当前适配器 void 在广告点击事件触发时调用
- (void)interstitialAdRenderSuccess:(id_Nonnull)adapter adapter: 当前适配器 void 在模板广告渲染成功时调用,非模板广告无需调用 模板广告: 是
- (void)interstitialAd:(id_Nonnull)adapter renderFailedWithError:(NSError *_Nullable)error adapter: 当前适配器 error: 渲染失败原因 void 在广告渲染失败时调用,非模板广告无需调用 模板广告: 是
- (void)interstitialAdWillPresentFullScreenModal:(id_Nonnull)adapter adapter: 当前适配器 void 在广告即将展示详情页或者appstore时调用
- (void)interstitialAdWillDismissFullScreenModal:(id_Nonnull)adapter adapter: 当前适配器 void 在广告关闭详情页或者appstore时调用

draw广告(Draw)

协议内容

自定义Draw adapter中需要实现的协议为CloooudCustomDrawAdapter,接口实现如下所示: | 方法名 | 参数说明 | 返回值 | 说明 | 是否必要 | | --- | --- | --- | --- | --- |

广告加载

在draw广告的adapter中使用如下方法完成广告加载,其中parameter参数包括了本次广告加载的所有数据,支持的参数详见下方加载参数部分,更完整信息请查看CloooudAdLoadingParams文件。

- (void)loadDrawAdWithSlotID:(nonnull NSString *)slotID andSize:(CGSize)size andParameter:(nonnull NSDictionary *)parameter {
    // 获取广告加载数量
    NSInteger count = [parameter[CloooudAdLoadingParamNALoadAdCount] integerValue];
    // 获取是否需要加载模板广告,非必要,视network支持而定
    NSInteger renderType = [parameter[CloooudAdLoadingParamExpressAdType] integerValue];
    // 模拟广告加载耗时,开发者需在此调用network加载广告方法
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        if (renderType == 1) { // 此处仅说明渲染类型可下发,开发者需根据实际定义情况编写
            // 模拟加载模板广告
            NSMutableArray *list = [NSMutableArray arrayWithCapacity:count];
            NSMutableArray *exts = [NSMutableArray arrayWithCapacity:count];
            for (int i = 0; i < count; i++) {
                CloooudDemoCustomExpressDrawView *view = [[CloooudDemoCustomExpressDrawView alloc] initWithSize:size];
                __weak typeof(self) ws = self;
                // 模拟广告点击事件
                view.didClickAction = ^(CloooudDemoCustomExpressDrawView * _Nonnull view) {
                    __strong typeof(ws) self = ws;
                    [self.bridge drawAd:self videoDidClick:view];
                    [self.bridge drawAd:self willPresentFullScreenModalWithMediatedAd:view];
                };
                // 模拟广告展示事件
                view.didMoveToSuperViewCallback = ^(CloooudDemoCustomExpressDrawView * _Nonnull view) {
                    __strong typeof(ws) self = ws;
                    [self.bridge drawAd:self didVisibleWithMediatedAd:view];
                };
                // 模拟广告关闭事件
                view.didClickCloseAction = ^(CloooudDemoCustomExpressDrawView * _Nonnull view) {
                    __strong typeof(ws) self = ws;
                    [self.bridge drawAd:self didCloseWithExpressView:view closeReasons:@[]];
                };
                view.viewController = self.bridge.viewControllerForPresentingModalView;
                [list addObject:view];
                [exts addObject:@{
                    CloooudMediaAdLoadingExtECPM : @"1000",
                }];
            }
            [self.bridge drawAd:self didLoadWithDrawAds:[list copy] exts:[exts copy]];
        } else {
            // 模拟加载非模板广告
            NSMutableArray *list = [NSMutableArray arrayWithCapacity:count];
            NSMutableArray *exts = [NSMutableArray arrayWithCapacity:count];
            for (int i = 0; i < count; i++) {
                CloooudDemoCustomDrawData *data = [CloooudDemoCustomDrawData randomData];
                __weak typeof(self) ws = self;
                // 模拟广告点击事件
                data.didClickAction = ^(CloooudDemoCustomDrawData * _Nonnull data) {
                    __strong typeof(ws) self = ws;
                    [self.bridge drawAd:self videoDidClick:data];
                    [self.bridge drawAd:self willPresentFullScreenModalWithMediatedAd:data];
                };
                data.viewController = self.bridge.viewControllerForPresentingModalView;
                id<CloooudMediatedNativeAdData, CloooudMediatedNativeAdViewCreator> helper = [[CloooudDemoCustomDrawAdHelper alloc] initWithAdData:data];
                // 构造需要返回Cloooud的非模板广告数据
                CloooudMediatedNativeAd *ad = [[CloooudMediatedNativeAd alloc] init];
                ad.originMediatedNativeAd = data;
                ad.view = ({
                    CloooudDemoCustomDrawView *v = [[CloooudDemoCustomDrawView alloc] init];
                    v.didMoveToSuperViewCallback = ^(CloooudDemoCustomDrawView * _Nonnull view) {
                        __strong typeof(ws) self = ws;
                        [self.bridge drawAd:self didVisibleWithMediatedAd:data]; // 注意:使用原始广告数据
                    }; v;
                });
                ad.viewCreator = helper;
                ad.data = helper;
                [list addObject:ad];
                [exts addObject:@{
                    CloooudMediaAdLoadingExtECPM : @"1000",
                }];
            }
            [self.bridge drawAd:self didLoadWithDrawAds:[list copy] exts:[exts copy]];
        }
    });
}

加载参数

参数名 参数类型 参数含义
CloooudAdLoadingParamLinkID NSString 聚合广告请求ID
CloooudAdLoadingParamMediationRitID NSString 聚合广告位ID
CloooudAdLoadingParamMediaRitID NSString ADN广告位ID
CloooudAdLoadingParamMediaName NSString ADN广告位名称,平台配置名称
CloooudAdLoadingParamExpressAdType NSNumber/NSInteger 请求广告的渲染类型,0 无需区分渲染类型; 1 ADN提供渲染; 2 开发者自渲染
CloooudAdLoadingParamExpressAdTypeInfos NSDictionary 是否请求模板广告的描述信息,仅为开发者提供说明,非请求参数
CloooudAdLoadingParamNAExpectImageSize NSValue/CGSize 期望展示尺寸
CloooudAdLoadingParamISExpectSize NSValue/CGSize 期望展示尺寸
CloooudAdLoadingParamNAIsMute NSNumber/BOOL 是否是静音
CloooudAdLoadingParamNALoadAdCount NSNumber/NSInteger 加载广告数量
CloooudAdLoadingParamCustomJson NSString(JSON) 自定义Adapter扩展参数,平台配置
CloooudAdLoadingParamBiddingType NSNumber/NSInteger 获取竞价类型,平台配置,0-普通广告位 1-Client竞价广告位 100-P层数据位

回调协议

开发者需通过回调方式将广告加载/展示/交互情况通知到Cloooud,以保证流程的完整性。协议内容详见CloooudCustomDrawAdapterBridge.h。

方法名 参数说明 返回值 说明 是否必要
- (void)drawAd:(id_Nonnull)adapter didLoadWithDrawAds:(NSArray _Nullable)ads exts:(NSArray<NSDictionary > * _Nullable)exts adapter: 当前适配器ads: 广告数据组 模板为视图类型数组,非模板为CloooudMediatedNativeAd类型数组exts: 需要回传的扩展数据,按照ads数组顺序匹配 void 在非模板广告加载完成时调用该方法
- (void)drawAd:(id_Nonnull)adapter didLoadFailWithError:(NSError *_Nullable)error; adapter: 当前适配器error: 广告加载出错的错误信息 void 在广告加载失败时调用该方法
- (void)drawAd:(id_Nonnull)adapter didVisibleWithMediatedAd:(id _Nonnull)drawAd; adapter: 当前适配器drawAd: 自渲染广告请传递原始数据(即CloooudMediatedNativeAd.originMediatedNativeAd),模板广告请传递上报expressView void 收到广告展示回调时调用该方法
- (void)drawAd:(id_Nonnull)adapter didClickWithMediatedAd:(id _Nonnull)drawAd; adapter: 当前适配器drawAd: 自渲染广告请传递原始数据(即CloooudMediatedNativeAd.originMediatedNativeAd),模板广告请传递上报expressView void 收到广告点击事件回调时调用该方法
- (void)drawAd:(id_Nonnull)adapter willPresentFullScreenModalWithMediatedAd:(id _Nonnull)drawAd; adapter: 当前适配器drawAd: 自渲染广告请传递原始数据(即CloooudMediatedNativeAd.originMediatedNativeAd),模板广告请传递上报expressView void 在广告即将展示详情页或者app store时调用
- (void)drawAd:(id_Nonnull)adapter willDismissFullScreenModalWithMediatedAd:(id _Nonnull)drawAd; adapter: 当前适配器drawAd: 自渲染广告请传递原始数据(即CloooudMediatedNativeAd.originMediatedNativeAd),模板广告请传递上报expressView void 在广告关闭详情页或者appstore时调用该方法
- (void)drawAd:(id_Nonnull)adapter didCloseWithMediatedAd:(id _Nonnull)drawAd closeReasons:(NSArray<CloooudDemoislikeWords > _Nullable)filterWords; adapter : 当前适配器drawAd : 自渲染广告请传递原始数据(即CloooudMediatedNativeAd.originMediatedNativeAd)filterWords : 用户手动关闭时的关闭原因描述 void 仅限自渲染广告,在广告关闭的时候调用
- (void)drawAd:(id_Nonnull)adapter renderSuccessWithExpressView:(UIView *_Nonnull)expressView; adapter : 当前适配器expressView 模板广告请传递上报expressView void 仅限模板广告,在渲染成功或者模板广告的尺寸更新时调用
- (void)drawAd:(id_Nonnull)adapter renderFailWithExpressView:(UIView _Nonnull)expressView andError:(NSError _Nonnull)error; adapter : 当前适配器expressView 模板广告请传递上报expressView void 仅限模板广告,在渲染失败调用
- (void)drawAd:(id_Nonnull)adapter didCloseWithExpressView:(UIView _Nonnull)expressView closeReasons:(NSArray<CloooudDemoislikeWords > *_Nullable)filterWords; adapter : 当前适配器expressView 模板广告请传递上报expressViewfilterWords : 用户手动关闭时的关闭原因描述 void 仅限模板广告,在模板广告关闭的时候调用
- (void)drawAd:(id_Nonnull)adapter videoStateDidChangedWithState:(CloooudPlayerPlayState)state andMediatedAd:(id _Nonnull)drawAd; adapter : 当前适配器state : 播放状态drawAd : 自渲染广告请传递原始数据(即CloooudMediatedNativeAd.originMediatedNativeAd),模板广告请传递上报expressView void 视频广告中视频播放状态变更的时候调用
- (void)drawAd:(id_Nonnull)adapter videoDidClick:(id _Nonnull)drawAd; adapter : 当前适配器drawAd : 自渲染广告请传递原始数据(即CloooudMediatedNativeAd.originMediatedNativeAd),模板广告请传递上报expressView void 视频广告中视频视图被点击时调用
- (void)drawAd:(id_Nonnull)adapter videoDidPlayFinish:(id _Nonnull)drawAd; adapter : 当前适配器drawAd : 自渲染广告请传递原始数据(即CloooudMediatedNativeAd.originMediatedNativeAd),模板广告请传递上报expressView --- 视频广告中视频播放完成时调用

综合比价支持

介绍

使自定义ADN的广告加载提供实时价格反馈渠道,参与到Cloooud的竞价逻辑中。在一定程度上实现开发者收益最大化。

参数下发

所有广告类型在已有参数基础上,补充CloooudAdLoadingParamBiddingType参数,该参数声明开发者在Cloooud平台配置的ADN广告竞价类型:

0:普通广告

1:客户端竞价广告

100:P层数据

数据类型为NSInteger,详情请见各广告类型加载参数部分。

价格回调

参与比价的价格应通过CloooudMediaAdLoadingExtECPM回调字段回传到Cloooud参与比价,该值为NSString类型,单位为分。

注意:

如ADN广告为非竞价类型,则CloooudMediaAdLoadingExtECPM回传价格无效;

如ADN广告为竞价类型,但CloooudMediaAdLoadingExtECPM值类型或内容错误,则无法参与比价。

比价结果通知

各广告Adapter协议中新增协议接口- (void)didReceiveBidResult:(CloooudMediaBidResult *)result通知adapter开发者比价结果。

参数为CloooudMediaBidResult类对象,该类中包含有竞价的结果信息,详情如下:

字段 类型 释义
win BOOL 是否在本次竞价中获胜
winnerPrice NSInteger 获胜者价格,可能为0
lossDescription NSString 竞价失败原因,竞价获胜时为nil
winnerAdnID NSString 竞价获胜者标识,可能为nil
ext NSDictionary 其他补充信息
originNativeAdData id Native广告时可用,用于区分Native广告

更多信息请参考各广告Adapter协议部分。

示例参考

如下:

- (void)loadRewardedVideoAdWithSlotID:(nonnull NSString *)slotID andParameter:(nonnull NSDictionary *)parameter {

CloooudBiddingType biddingType = [parameter[CloooudAdLoadingParamBiddingType] integerValue];

__weak typeof(self) ws = self;

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

__strong typeof(ws) self = ws;

if (biddingType != CloooudBiddingTypeClient) {

// 模拟加载广告成功

[self.bridge rewardedVideoAd:self didLoadWithExt:@{}];

} else {

// 模拟加载广告成功

[self.bridge rewardedVideoAd:self didLoadWithExt:@{

CloooudMediaAdLoadingExtECPM : @"100"

}];

}

// 模拟广告视频资源加载成功,可选

[self.bridge rewardedVideoAdVideoDidLoad:self];

});

}

- (void)didReceiveBidResult:(CloooudMediaBidResult *)result {

// 在此处理Client Bidding的结果回调

}