Topon SDK v5.7.05 and above are supported.
This document mainly introduces how to customize the Adapter to integrate Client Bidding. For more customized Adapter implementation, please refer to this document Customized advertising platform
Client Bidding loading The process is as shown in the figure:
Abstract method | Parameter description | Return value | Function | Must be implemented |
---|---|---|---|---|
+ (void)bidRequestWithPlacementModel: (ATPlacementModel *)placementModel unitGroupModel:(ATUnitGroupModel *)unitGroupModel info:(NSDictionary *)info completion:(void(^)(ATBidInfo *bidInfo, NSError *error))completion | completion: When header bidding is completed, this callback needs to be executed to return the data or errors obtained by bidding to Topon SDK | void | To implement custom header bidding, you must implement Class method | Yes |
+ (void)sendWinnerNotifyWithCustomObject:(id)customObject secondPrice:(NSString*)price userInfo:(NSDictionary | customObject is the advertising object | void | To implement custom header bidding, you must implement Class method | No |
+(void)sendLossNotifyWithCustomObject:(nonnull id)customObject lossType:(ATBiddingLossType)lossType winPrice:(nonnull NSString *) price userInfo:(NSDictionary *)userInfo; | customObject is the advertising object, lossType is the bid failure reason | void | To implement custom header bidding, you must implement Class method | No |
The following uses Baidu as an example, C2S code implementation
Introduce the header file
#import <AnyThinkSDK/AnyThinkSDK.h>
@interface BaiduRewardedVideoAdapter()
Add the following method, which is a required implementation method for the protocol, and implement the following logical steps in this method:
+ (void)bidRequestWithPlacementModel:(ATPlacementModel*)placementModel unitGroupModel:(ATUnitGroupModel*)unitGroupModel info:(NSDictionary*)info completion:(void(^)(ATBidInfo *bidInfo, NSError *error))completion {
// 1. Initiate an AD source C2S header bidding request.
...
// If bidding fails, a callback is performed, passing an error
NSError *error = ...;
if (error) {
completion(nil, error);
return;
}
// 2. Gets the price returned by the AD source C2S header bidding and constructs the ATBidInfo object.
NSString *price = ...;
// You need to verify that the currency unit currencyType is passed in
ATBidInfo *info = [ATBidInfo bidInfoC2SWithPlacementID:placementModel.placementID
unitGroupUnitID:unitGroupModel.unitID
adapterClassString:request.unitGroup.adapterClassString
price:price
currencyType:ATBiddingCurrencyTypeCNY
expirationInterval:unitGroupModel.networkTimeout
customObject:nil];
//3. Calls the completion block and passes in the ATBidInfo object
completion(info, nil);
}
Finally, you need to adjust the loadAdWithInfo method logic in the Adapter class. Please refer to the following :
- (void)loadWithServerInfo:(NSDictionary *)serverInfo localInfo:(NSDictionary *)localInfo {
NSString *bidId = serverInfo[kATAdapterCustomInfoBuyeruIdKey];
// If there is bidId, the representative is the header bidding AD source
if (bidId) {
// Determine if the AD source has been loaded
if (_rewardedVideo.isReady) {
[_customEvent trackRewardedVideoAdLoaded:_rewardedVideo adExtra:nil];
}
}
.....
}
At this point, you can develop C2S requests based on your business logic, but if you need a more complete example, you can continue to read below.
Inherit the ATRewardedVideoCustomEvent object, introduce the header file.
#import <AnyThinkSDK/AnyThinkSDK.h>
@interface BaiduRewardedVideoAdapter()
In fact, most advertising platforms request data after It is called back through delegate. So you need to create a class to receive callbacks. The following is a simple example in ATBaiduRewardedVideoCustomEvent.
#import "ATRewardedVideoCustomEvent.h"
#import "ATBaiduRewardedVideoAdapter.h"
##import <BaiduMobAdSDK/BaiduMobAdRewardVideo.h>
@interface ATBaiduRewardedVideoCustomEvent : ATRewardedVideoCustomEvent
@property (nonatomic, assign) BOOL isC2SBiding;
@end
@interface ATBaiduRewardedVideoCustomEvent()
@end
@implementation ATBaiduRewardedVideoCustomEvent
- (void)rewardedVideoAdLoaded:(BaiduMobAdRewardVideo *)video {
if (self.isC2SBiding) {
NSString *price = @"Replace it with the price your AD platform gets"
// Prices used for sorting
NSString *sortPrice = @"Replace it with what you need";
// Construct the ATBidInfo object to return to the 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];
// Calling bidCompletion returns bidInfo to the 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
Use a BiddingRequest to save C2S request data.
@interface ATBaiduBiddingRequest : NSObject
@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
Create an ATBaiduC2SBiddingRequestManager class to save the request in memory
#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
Add the following logic to the method.
+ (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;
// Create an ATBaiduBiddingRequest class to hold the information required for the request
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;
// The AD source calls back to the customEvent object
request.customEvent = customEvent;
// Create a ATBaiduC2SBiddingRequestManager class, used to hold the request in memory
[[ATBaiduC2SBiddingRequestManager sharedInstance] startWithRequestItem:request];
}
Final adjustment [BaiduRewardedVideoAdapter loadWithServerInfo:(NSDictionary *)serverInfo localInfo:(NSDictionary *)localInfo]
- (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
}
Parameter description:
Parameter name | Parameter description |
---|---|
AdapterName | Customized advertising platform class name |
networkCacheTime | Cache time of the AD source dimension (in milliseconds) |
bidRealTimeLoadSW | Real-time bidding for each load in the ad source dimension switch |
NSMutableArray *array = [NSMutableArray array];
ATCustomNetworkMode *splshMode = [[ATCustomNetworkMode alloc]initWithAdapterName:@"AdapterName" networkCacheTime:1800 bidRealTimeLoadSW:YES];
[array addObject:splshMode];
[ATAPI addCustomAdapterConfigArray:array];