Taku SDK v5.7.05 及以上版本支持。
此文档主要介绍如何自定义Adapter集成Client Bidding,更多自定义Adapter实现请参考此文档 自定义广告平台
Client Bidding加载流程如图:
抽象方法 | 参数说明 | 返回值 | 作用 | 必须实现 |
---|---|---|---|---|
+ (void)bidRequestWithPlacementModel:(ATPlacementModel *)placementModel unitGroupModel:(ATUnitGroupModel *)unitGroupModel info:(NSDictionary *)info completion:(void(^)(ATBidInfo *bidInfo, NSError *error))completion | completion: 当 header bidding 完成后,需要执行此回调,将 bidding 得到的数据或者错误回传给 Taku SDK | void | 要实现自定义header bidding,则必须实现类方法 | 是 |
+ (void)sendWinnerNotifyWithCustomObject:(id)customObject secondPrice:(NSString*)price userInfo:(NSDictionary | customObject为当广告对象 | void | 要实现自定义header bidding,则必须实现类方法 | 否 |
+ (void)sendLossNotifyWithCustomObject:(nonnull id)customObject lossType:(ATBiddingLossType)lossType winPrice:(nonnull NSString *)price userInfo:(NSDictionary *)userInfo; | customObject为当广告对象,lossType 为 bid失败原因 | void | 要实现自定义header bidding,则必须实现类方法 | 否 |
实现上面的方法,以Baidu为例子,C2S代码实现
引入头文件
#import <AnyThinkSDK/AnyThinkSDK.h>
@interface BaiduRewardedVideoAdapter()
添加以下的方法,该方法为协议必须实现方法,并在该方法里实现以下逻辑步骤:
+ (void)bidRequestWithPlacementModel:(ATPlacementModel*)placementModel unitGroupModel:(ATUnitGroupModel*)unitGroupModel info:(NSDictionary*)info completion:(void(^)(ATBidInfo *bidInfo, NSError *error))completion {
// 1. 发起广告源C2S header bidding请求。
...
// 如果 bidding 失败,则执行回调,传入error
NSError *error = ...;
if (error) {
completion(nil, error);
return;
}
// 2. 获取广告源C2S header bidding返回的价格,并构造出ATBidInfo对象。
NSString *price = ...;
// 需要确认一下传入的货币单位 currencyType
ATBidInfo *info = [ATBidInfo bidInfoC2SWithPlacementID:placementModel.placementID
unitGroupUnitID:unitGroupModel.unitID
adapterClassString:request.unitGroup.adapterClassString
price:price
currencyType:ATBiddingCurrencyTypeCNY
expirationInterval:unitGroupModel.networkTimeout
customObject:nil];
// 然后回传给 Taku SDK
**注意:5.9.90版版本以实现以下方法可忽略重写loadADWithInfo方法**
// bidInfo.isC2SNotNeedLoad = YES;
// bidInfo.c2SCustomEvent = customEvent;
// bidInfo.c2sCustomObject = customObject;
//3. 调用completion block,并将ATBidInfo对象传入
completion(info, nil);
}
最后需要调整 Adapter 类里的 loadAdWithInfo 方法逻辑,参考如下:
- (void)loadWithServerInfo:(NSDictionary *)serverInfo localInfo:(NSDictionary *)localInfo {
NSString *bidId = serverInfo[kATAdapterCustomInfoBuyeruIdKey];
//如果有bidId,代表是header bidding广告源
if (bidId) {
//判断广告源是否已经loaded过
if (_rewardedVideo.isReady) {
[_customEvent trackRewardedVideoAdLoaded:_rewardedVideo adExtra:nil];
}
}
.....
}
至此根据你的业务逻辑,已经可以开发C2S的请求了,但是如果需要较为完整例子,可以继续往下看。
引入头文件
#import <AnyThinkSDK/AnyThinkSDK.h>
@interface BaiduRewardedVideoAdapter()
实质大多数广告平台请求数据后是通过 delegate 回调的。所以需要创建一个类来接收回调,以下是 ATBaiduRewardedVideoCustomEvent中简单的示例。
#import "ATRewardedVideoCustomEvent.h"
#import "ATBaiduRewardedVideoAdapter.h"
#import <BaiduMobAdSDK/BaiduMobAdRewardVideo.h>
@@interface ATBaiduRewardedVideoCustomEvent : ATRewardedVideoCustomEvent<BaiduMobAdRewardVideoDelegate>
@property (nonatomic, assign) BOOL isC2SBiding;
@end
@interface ATBaiduRewardedVideoCustomEvent()
@end
@implementation ATBaiduRewardedVideoCustomEvent
- (void)rewardedVideoAdLoaded:(BaiduMobAdRewardVideo *)video {
if (self.isC2SBiding) {
NSString *price = @"替换成你的广告平台获取到的价格"
//用于排序的价格
NSString *sortPrice = @"替换成你需要";
//构造ATBidInfo对象用于返回给SDK
ATBidInfo *bidInfo = [ATBidInfo bidInfoC2SWithPlacementID:request.placementID unitGroupUnitID:request.unitGroup.unitID adapterClassString:request.unitGroup.adapterClassString price:priceStr sortPrice:sortPrice currencyType:ATBiddingCurrencyTypeUS expirationInterval:request.unitGroup.bidTokenTime customObject:customObject];
bidInfo.networkFirmID = request.unitGroup.networkFirmID;
bidInfo.curRate = [self handleRateForBidInfo:bidInfo];
//调用bidCompletion返回bidInfo给SDK
if (request.bidCompletion) {
request.bidCompletion(bidInfo, nil);
}
self.isC2SBiding = NO;
}
......
}
- (void)rewardedVideoAdLoadFailed:(BaiduMobAdRewardVideo *)video withError:(BaiduMobFailReason)reason {
if (self.isC2SBiding) {
[self trackRewardedVideoAdLoadFailed:[NSError errorWithDomain:@"com.anythink.BaiduRewardedVideo" code:reason userInfo:@{NSLocalizedDescriptionKey:kATSDKFailedToLoadRewardedVideoADMsg, NSLocalizedFailureReasonErrorKey:@"BaiduSDK has failed to load rewarded video."}]];
}
.....
}
@end
使用一个BiddingRequest来保存C2S请求数据。
@interface ATBaiduBiddingRequest : NSObject<ATC2SBiddingParameterProtocol>
@property(nonatomic, strong) id customObject;
@property(nonatomic, strong) ATUnitGroupModel *unitGroup;
@property(nonatomic, strong) ATAdCustomEvent *customEvent;
@property(nonatomic, copy) NSString *unitID;
@property(nonatomic, copy) NSString *placementID;
@property(nonatomic, copy) NSString *publisherID;
@property(nonatomic, copy) NSDictionary *extraInfo;
@end
创建一个ATBaiduC2SBiddingRequestManager类,用于保存request在内存当中
#import <Foundation/Foundation.h>
#import "ATBaiduBiddingRequest.h"
#import "ATC2SBiddingParameterManager.h"
NS_ASSUME_NONNULL_BEGIN
@interface ATBaiduC2SBiddingRequestManager : NSObject
+ (instancetype)sharedInstance;
- (void)startWithRequestItem:(ATBaiduBiddingRequest *)request;
@end
@implementation ATBaiduC2SBiddingRequestManager
+ (instancetype)sharedInstance {
static ATBaiduC2SBiddingRequestManager *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[ATBaiduC2SBiddingRequestManager alloc] init];
});
return sharedInstance;
}
- (void)startWithRequestItem:(ATBaiduBiddingRequest *)request {
NSString *adplaceidStr = request.unitGroup.content[@"ad_place_id"];
[[ATC2SBiddingParameterManager sharedInstance] saveRequestItem:request withUnitId:adplaceidStr];
dispatch_async(dispatch_get_main_queue(), ^{
NSString *appidStr = request.unitGroup.content[@"app_id"];
NSString *adplaceidStr = request.unitGroup.content[@"ad_place_id"];
BaiduMobAdRewardVideo *rewardedVideo = [[BaiduMobAdRewardVideo alloc] init];
rewardedVideo.delegate = request.customEvent;
rewardedVideo.AdUnitTag = adplaceidStr;
rewardedVideo.publisherId = appidStr;
request.customObject = rewardedVideo;
[rewardedVideo load];
});
}
NS_ASSUME_NONNULL_END
必须要实现的方法添加以下逻辑:
+ (void)bidRequestWithPlacementModel:(ATPlacementModel*)placementModel unitGroupModel:(ATUnitGroupModel*)unitGroupModel info:(NSDictionary*)info completion:(void(^)(ATBidInfo *bidInfo, NSError *error))completion {
ATBaiduRewardedVideoCustomEvent *customEvent = [[ATBaiduRewardedVideoCustomEvent alloc] initWithInfo:info localInfo:info];
customEvent.isC2SBiding = YES;
//创建一个ATBaiduBiddingRequest类用于保存请求所需要的信息
ATBaiduBiddingRequest *request = [ATBaiduBiddingRequest new];
request.unitGroup = unitGroupModel;
request.placementID = placementModel.placementID;
request.bidCompletion = completion;
request.unitID = info[@"ad_place_id"];
request.extraInfo = info;
request.adType = ATAdFormatRewardedVideo;
//广告源回调到customEvent对象
request.customEvent = customEvent;
//创建一个ATBaiduC2SBiddingRequestManager类,用于保存request在内存当中
[[ATBaiduC2SBiddingRequestManager sharedInstance] startWithRequestItem:request];
}
最后调整 BaiduRewardedVideoAdapter 类中的方法
- (void)loadWithServerInfo:(NSDictionary *)serverInfo localInfo:(NSDictionary *)localInfo {
NSString *bidId = serverInfo[kATAdapterCustomInfoBuyeruIdKey];
if (bidId) {
ATBaiduBiddingRequest *request = [[ATC2SBiddingParameterManager sharedInstance] getRequestItemWithUnitID:serverInfo[@"ad_place_id"]];
if (request != nil) {
if (request.customObject) {
_rewardedVideo = request.customObject;
_rewardedVideo.delegate = _customEvent;
if (_rewardedVideo.isReady) {
[_customEvent trackRewardedVideoAdLoaded:_rewardedVideo adExtra:nil];
} else {
[_rewardedVideo load];
}
}
// remove requestItem
[[ATC2SBiddingParameterManager sharedInstance] removeRequestItemWithUnitID:serverInfo[@"ad_place_id"]];
}
} BaiduRewardedVideoAdapter
}
参数说明:
参数名称 | 参数说明 |
---|---|
AdapterName | 自定义广告平台类名 |
networkCacheTime | 广告源维度的缓存时间 (单位:毫秒) |
bidRealTimeLoadSW | 广告源维度的每次Load均实时竞价开关 |
NSMutableArray *array = [NSMutableArray array];
ATCustomNetworkMode *splshMode = [[ATCustomNetworkMode alloc]initWithAdapterName:@"AdapterName" networkCacheTime:1800 bidRealTimeLoadSW:YES];
[array addObject:splshMode];
[ATAPI addCustomAdapterConfigArray:array];