Mintegral SDK支持在移动应用中竞价。移动应用竞价集成可以是从移动客户端到我们的服务器。此概述将涵盖应用出价的一般概念,并提供有关如何将应用程序标头与Mintegral SDK集成的说明。
Mintegral SDK提供6种不同的广告格式,包括横幅,原生,原生视频,奖励视频,插屏视频,开屏,并且可以支持App Head-Bidding。
一、介绍
1.1 什么是App Head-Bidding
应用头部竞价可以让开发者在展示广告之前,通过竞价请求获取每个广告平台的出价,并通过竞价排序选出胜出者,只有胜出的广告平台才可以获得广告展示机会,进而使得广告展示的收益趋于最大化。
1.2 为什么要App Head-Bidding
二、集成介绍
Mintegral提供两种Header Bidding方式,分别是:客户端到服务端竞价,服务端到服务端竞价。 开发者可根据自身实际情况进行选择,并按照相应流程执行逻辑
2.1 客户端到服务端竞价说明
在这种流程中,开发者可通过Mintegral SDK进行竞价请求,并可在客户端进行竞价排序。
关键步骤:
开发者APP在展示机会到来之前完成初始化并调用Mintegral sdk竞价请求接口,Mintegral SDK会与服务端通信获取竞价返回结果。
开发者APP通过返回的结果,获取价格和bidtoken(调用广告加载方法时会用到该字段)
若Mintegral竞价成功,开发者可以调用我们sdk的广告加载接口进行广告加载并进行后续展示。
2.2 服务端到服务端竞价
在本流程中,开发者可通过自有服务器(或通过第三方聚合服务器)进行竞价请求,并可在服务端进行竞价排序。
关键步骤:
开发者在展示机会到来之前完成初始化并调用Mintegral SDK的 BidManager.getBuyerUid 接口来获取buyeruid(可选)
开发者app可将获取到的buyeruid上报给自己服务器,用于请求Mintegral服务器时进行传递(可选)
开发者服务端需构造符合OpenRTB协议标准(参照说明)的请求向Mintegral广告平台服务器发起竞价请求询价
我们的广告服务器响应竞价请求并进行出价,开发者可以在自身的服务端进行竞价排序,选出胜出的广告平台,同时下发相关响应参数包括bidid(调用广告加载方法时会用到该字段)
开发者服务器通知自己的客户端Mintegral胜出,开发者APP调用Mintegral sdk的广告加载接口进行广告加载。
三、SDK集成接入说明
3.1 Android集成说明
3.1.1 获取Mintegral SDK
添加mbbid.aar(jar) 和 same.aar(jar)到你的项目中。 或从远程仓库拉取。(请保证Bid SDK和您的Mtg SDK版本号一致)
Copy //支持Android X 版本 并且是上架谷歌应用市场
implementation 'com.mbridge.msdk.oversea:mbbid:15.5.41'
//支持Android X 版本 不上架谷歌应用市场
implementation 'com.mbridge.msdk.china:mbbid:15.5.42'
//不支持Android X 版本,不上架谷歌应用市场
implementation 'com.mbridge.msdk.support:mbbid:15.5.47'
3.1.2 初始化SDK
在application中调用初始化方法,传入在Mintergal后台得到的AppID和AppKey。建议在主线程调用此方法,并且尽量在你应用启动时,越早初始化SDK越好。保证每次重新启动应用的时候都要完成初始化sdk。注意AppId、AppKey及请求广告的unitId都必须填写,不能置空。
Copy public void init(Map<String,String> ids,Application application);
示例代码:
Copy MBridgeSDK sdk = MBridgeSDKFactory.getMBridgeSDK();
Map<String, String> map = sdk.getMBConfigurationMap("your AppId", "your AppKey");
sdk.init(map, this);
3.1.3 创建BidManager对象并竞价请求
注:若您采用服务端到服务端竞价模式可忽略该步骤
在你项目里的Activity或者Fragment,创建BidManager对象:
Copy BidManager manager = new BidManager("your placementId", "your unitID");
//如果集成Banner类型广告,传入BannerBidRequestParams
manager = new BidManager(new BannerBidRequestParams(String placementId, String mUnitId, int weigh, int height));
//如果集成Splash类型广告,传入SplashBidRequestParams
manager = new BidManager(new SplashBidRequestParams(String placementId, String mUnitId, boolean ispreload, int orientation, int logoSizeW, int logoSizeH));
在BidManager对象创建好了之后,可以通过bid方法来发送竞价请求,并且回调一个BidListennning对象。注意在调用bid方法前,一定要保证SDK初始化完成。
Sample code:
Copy BidManager manager = new BidManager("your placementId", "your unitID");
//集成Banner类型广告传入BannerBidRequestParams
manager = new BidManager(new BannerBidRequestParams(UNIT_ID,bannerW,bannerH));
manager.setBidListener(new BidListennning() {
@Override
public void onFailed(String msg) {
// bid failed
}
@Override
public void onSuccessed(BidResponsed bidResponsed) {
// bid successeful
}
});
//如果使用Reward Plus,需要添加以下代码在bid方法前
manager.setRewardPlus(true);
manager.bid();
3.1.4 处理竞价结果
注:本段落描述内容为在客户端处理竞价结果的示例,若您采用服务端到服务端竞价模式需在服务端进行竞价结果的处理
在这部分中,我们采用MBridgeSDK的出价响应,并将其与其他买家的CPM价格进行比较,并决定MintegralSDK是赢得并加载广告,还是失败。 当您确定拍卖结果时,请调用方法sendWinNotice(Context context)或sendLossNotice(Context context,BidLossCode bidLossCode)以通知MTG结果。
请注意,拍卖逻辑由应用程序本身实现。 它应该简单地比较投标价格并选择最高出价者作为拍卖获胜者。
以下是如何使用返回的BidResponsed并运行竞价的示例。
Copy ...
@Override
public void onSuccessed(BidResponsed bidResponsed) {
token = bidResponsed.getBidToken();
final double otherPrice = ...;
final double price = bidResponsed.getPrice();
if (price >= otherPrice) {
// Load the ad from the bid response
// Notify the bid won
bidResponsed.sendWinNotice(getApplicationContext());
} else {
// Notify the bid lose
bidResponsed.sendLossNotice(getApplicationContext(),bidLossCode);
//bidLossCode分为三种,根据实际情况选择
//BidLossCode.bidPriceNotHighest() bid价格不是最高的
//BidLossCode.bidTimeOut() bid超时
//BidLossCode.bidWinButNotShow() bid成功了但是不展示
}
}
...
3.1.5 根据竞价结果,加载对应的广告
当Mintegral赢得竞价后,下一步是使用MBBannerView的loadFromBid(String bidToken)方法来请求广告。此部分与普通请求广告很相似,只有一处不同,您需要调用loadFromBid(String bidToken)来请求广告,而不是调用load()方法。其中对于bidToken,对于客户端到服务端集成方式您可以通过这样来获取:bidResponsed.getBidToken()</br> 若您使用服务端到服务端集成方式需将Mintegral返回的bidid作为bidtoken传入进行广告加载 Object:BidResponse 。
监听器的回调方法与普通请求广告对象监听器是一样的。
Sample Code:
Copy mbBannerView.init(new BannerSize(BannerSize.DEV_SET_TYPE,bannerW,bannerH),UNIT_ID);
//mbBannerView.setAllowShowCloseBtn(false);
mbBannerView.setRefreshTime(10);
mbBannerView.setBannerAdListener(new BannerAdListener() {
@Override
public void onLoadSuccessed() {
showToast("on load successd");
Log.e(TAG, "on load successed");
}
...
...
});
mbBannerView.loadFromBid(token);
当MBridgSDK赢得竞价后,下一步是使用MBBidNativeHandler的bidLoad(String bidToken)方法来请求广告。此部分与普通请求广告很相似,只有一处不同,您需要调用bidLoad(String bidToken)来请求广告,而不是调用load()方法。其中对于bidToken,对于客户端到服务端集成方式您可以通过这样来获取:bidResponsed.getBidToken()</br> 若您使用服务端到服务端集成方式需将Mintegral返回的bidId作为bidtoken传入进行广告加载 Object:BidResponse 。
监听器的回调方法与普通请求广告对象监听器是一样的。
Sample Code:
Copy Map<String, Object> properties = MBNativeHandler.getNativeProperties("your placementId", "your unitId");
properties.put(MIntegralConstans.PROPERTIES_AD_NUM, AD_NUM);
mNativeHandle = new MBBidNativeHandler(properties, this);
mNativeHandle.setAdListener(new NativeAdListener() {
@Override
public void onAdLoaded(List<Campaign> campaigns, int template) {
}
...
...
});
mNativeHandle.bidLoad("the bidToken");
...
...
当MintegralSDK赢得竞价后,下一步是使用MBBidRewardVideoHandler的loadFromBid(String bidToken)方法来请求广告。此部分与普通请求广告很相似,只有一处不同,您需要调用loadFromBid(String bidToken)来请求广告,而不是调用load()方法。其中对于bidToken,客户端到服务端集成方式中您可以通过这样来获取:bidResponsed.getBidToken()</br> 若您使用服务端到服务端集成方式需将Mintegral返回的bidid作为bidtoken传入进行广告加载Object:BidResponse 。
监听器的回调方法与普通请求广告对象监听器是一样的。
Sample code:
Copy public class TestActivity extends Activity implements View.OnClickListener{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
...
...
MBBidRewardVideoHandler mMbRewardVideoHandler = new MBBidRewardVideoHandler(this, "your placementId", "your unitId");
mMbRewardVideoHandler.setRewardVideoListener(new RewardVideoListener() {
@Override
public void onLoadSuccess(String placementId, String unitId) {
}
@Override
public void onVideoLoadSuccess(String placementId, String unitId) {
}
...
...
//如果需要使用RewarPlus,则需要添加以下代码
mMbRewardVideoHandler.setRewardPlus(true);
});
}
...
...
...
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_load:
mMbRewardVideoHandler.loadFromBid("the bidToken");
break;
case R.id.bt_show:
if (mMbRewardVideoHandler.isBidReady()) {
mMbRewardVideoHandler.showFromBid("your rewardId");
}
break;
}
}
}
当MTGSDK赢得竞价后,下一步是使用MBBidInterstitialVideoHandler的loadFromBid(String bidToken)方法来请求广告。此部分与普通请求广告很相似,只有一处不同,您需要调用loadFromBid(String bidToken)来请求广告,而不是调用load()方法。其中对于bidToken,客户端到服务端集成方式中您可以通过这样来获取:bidResponsed.getBidToken()</br> 若您使用服务端到服务端集成方式需将Mintegral返回的bidId作为bidtoken传入进行广告加载Object:BidResponse 。
监听器的回调方法与普通请求广告对象监听器是一样的。
Sample code:
Copy public class TestActivity extends Activity implements View.OnClickListener{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
...
...
MBBidInterstitialVideoHandler mMbInterstitalVideoHandler = new MBBidInterstitialVideoHandler(this, "your placementId", "your unitId");
mMbInterstitalVideoHandler.setInterstitialVideoListener(new InterstitialVideoListener() {
@Override
public void onLoadSuccess(String placementId, String unitId) {
}
@Override
public void onVideoLoadSuccess(String placementId, String unitId) {
}
...
...
});
}
...
...
...
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_load:
mMbInterstitalVideoHandler.loadFromBid("the bidToken");
break;
case R.id.bt_show:
if (mMbInterstitalVideoHandler.isBidReady()) {
mMbInterstitalVideoHandler.showFromBid("your rewardId");
}
break;
}
}
}
当MTGSDK赢得竞价后,下一步是使用MBSplashHandler的preLoadByToken(String token)或者loadAndShowByToken(String token, ViewGroup container)方法来请求广告。此部分与普通请求广告很相似,只有一处不同,您需要调用preLoadByToken(String token)或者loadAndShowByToken(String token, ViewGroup container)来请求广告,而不是调用preLoad()或 loadAndShow( ViewGroup container)方法。其中对于bidToken,客户端到服务端集成方式中您可以通过这样来获取:bidResponsed.getBidToken()</br> 若您使用服务端到服务端集成方式需将Mintegral返回的bidId作为bidtoken传入进行广告加载Object:BidResponse 。
监听器的回调方法与普通请求广告对象监听器是一样的。
Sample code:
Copy bidManager = new BidManager(new SplashBidRequestParams("your placementId", unitId, true, 2, 30, 30));
mbSplashHandler = new MBSplashHandler("your placementId", unitId);
mbSplashHandler.setLoadTimeOut(loadTimeOut);
Button textView = new Button(this);
textView.setText("logo");
mbSplashHandler.setLogoView(textView, 100, 100);
mbSplashHandler.setSplashLoadListener(new MBSplashLoadListener() {
@Override
public void onLoadSuccessed(int reqType) {
}
@Override
public void onLoadFailed(String msg, int reqType) {
}
}
mbSplashHandler.setSplashShowListener(new MBSplashShowListener() {
@Override
public void onShowSuccessed() {
}
@Override
public void onShowFailed(String msg) {
}
...
...
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.mbridge_demo_splash_ac_bid:
bidManager.bid();
break;
case R.id.mbridge_demo_splash_ac_load_show:
if(!TextUtils.isEmpty(token)){
mbSplashHandler.loadAndShowByToken(token,container);
}else {
Toast.makeText(BidSplashActivity.this,"Token is empty",Toast.LENGTH_LONG).show();
}
break;
case R.id.mbridge_demo_splash_ac_preload:
if (!TextUtils.isEmpty(token)) {
mbSplashHandler.preLoadByToken(token);
}else {
Toast.makeText(BidSplashActivity.this,"Token is empty",Toast.LENGTH_LONG).show();
}
break;
case R.id.mbridge_demo_splash_ac_show:
if (!TextUtils.isEmpty(token)) {
if (mbSplashHandler.isReady(token)) {
mbSplashHandler.show(container,token);
} else {
Log.e(TAG, "isready is false");
Toast.makeText(BidSplashActivity.this,"campain is not ready",Toast.LENGTH_LONG).show();
}
}else {
Toast.makeText(BidSplashActivity.this,"Token is empty",Toast.LENGTH_LONG).show();
}
break;
}
}
3.1.6 获取buyerUID(可选项)
注:该步骤主要在服务端到服务端对接模式中用到,若开发者采用客户端到服务端对接模式则无需获取buyeruid。获取并使用该参数有助于更好地让Mintegral算法更好地进行广告优化,但本步骤不是强制的。
通过调用静态方法 BidManager.getBuyerUid(Context context) 来获取唯一的buyerUID,并将这个buyerUID告知你自己的服务端,用于执行服务端的竞价请求Object:User ,建议您在每次初始化应用后或竞价请求前重新获取buyerUID。
3.2 iOS集成说明
3.2.1获取Mintegral SDK
添加MTGSDK.framework 和 MTGBidding.framework到你的项目中。
3.2.2 初始化SDK
在AppDelegate里的如下方法中调用MTGSDK的初始化方法,传入在Mintergal后台得到的AppID和ApiKey。初始化时,MTGSDK会从服务器拉取配置信息。建议在主线程调用此方法。注意AppId、ApiKey及请求广告的unitId都必须填写,不能置空。
Copy //tips:ApiKey and AppKey are the same.
- (void)setAppID:(nonnull NSString *)appID ApiKey:(nonnull NSString *)appKey;
示例代码:
Copy - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
[[MTGSDK sharedInstance] setAppID:@"your appID" ApiKey:@"your apiKey"];
}
3.2.3 创建MTGBiddingRequest对象并竞价请求
注:若您采用服务端到服务端竞价模式可忽略该步骤
SDK初始化完成之后,在你的iOS项目中,创建如下代码:(在调用该方法前一定要保证初始化完成)
Copy [MTGBiddingRequest getBidWithRequestParameter:param completionHandler:^(MTGBiddingResponse * _Nonnull bidResponse) {
if (bidResponse.success) {
//bid successeful
}else{
//bid failed
}
}];
3.2.4 处理竞价结果
注:本段落描述内容为在客户端处理竞价结果的示例,若您采用服务端到服务端竞价模式需在服务端进行竞价结果的处理。
在这部分中,我们采用MintegralSDK的出价响应,并将其与其他买家的CPM价格进行比较,并决定MintegralSDK是赢得并加载广告,还是失败。 当您确定拍卖结果时,请调用方法notifyWin或notifyLoss以通知MTG结果。
请注意,拍卖逻辑由应用程序本身实现。 它应该简单地比较投标价格并选择最高出价者作为拍卖获胜者。
以下是如何使用返回的MTGBiddingResponse并运行竞价的示例。
Copy //如果集成Banner类型广告,创建MTGBiddingBannerRequestParameter
MTGBiddingBannerRequestParameter *bannerParam = [[MTGBiddingBannerRequestParameter alloc]initWithPlacementId:kBannerPlacementId unitId:kBannerUnitID basePrice:@0.1 unitSize:CGSizeMake(320, 50)];
//如果集成Splash类型广告,创建MTGBiddingSplashRequestParameter
MTGBiddingSplashRequestParameter *param = [[MTGBiddingSplashRequestParameter alloc] initWithPlacementId:kSplashPlacementId unitId:kSplashUnitID basePrice:@(0) preload:YES customViewSize:CGSizeMake(100, 100) preferredOrientation:0];
//如果使用Reward Plus
//This method is used to open RewardPlus for RewardVideo,if you need,defalue NO.
MTGBiddingRequestParameter *requestParameter = [[MTGBiddingRequestParameter alloc]initWithPlacementId:kRewardPlacementId unitId:KRewardUnitID basePrice:@(0.1) openRewardPlus:YES];
//其他广告形式,创建MTGBiddingRequestParameter
MTGBiddingRequestParameter *param = [[MTGBiddingRequestParameter alloc]initWithPlacementId:KNativePlacementId unitId:KNativeUnitID basePrice:nil];
[MTGBiddingRequest getBidWithRequestParameter:param completionHandler:^(MTGBiddingResponse * _Nonnull bidResponse) {
if (bidResponse.success) {
self.bidToken = bidResponse.bidToken;
[self log:@"bid success"];
[bidResponse notifyWin];
}else{
NSString *errorMsg = bidResponse.error.description;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Bid Failed" message:errorMsg delegate:nil cancelButtonTitle:@"Got" otherButtonTitles:nil];
[alert show];
[self log:@"bid failed"];
}
}];
3.2.5 根据竞价结果,加载对应的广告
当MTGSDK出价赢得竞价后,下一步是使用loadBannerAdWithBidToken 方法来请求广告。
此部分与普通请求广告很相似,只有一处不同,您需要调用loadBannerAdWithBidToken来请求广告,而不是调用loadBannerAd 方法。其中对于bidToken,客户端到服务端集成方式中您可以通过这样来获取:bidResponse.bidToken,若您使用服务端到服务端集成方式需将Mintegral返回的bidid作为bidtoken传入进行广告加载 Object:BidResponse 。
Delegate的回调方法与普通请求广告是一样的。
Sample Code:
Copy #import "TestViewController.h"
#import <MTGSDKBanner/MTGBannerAdView.h>
#import <MTGSDKBanner/MTGBannerAdViewDelegate.h>
#import <MTGSDKBidding/MTGBiddingRequest.h>
#import <MTGSDKBidding/MTGBiddingBannerRequestParameter.h>
@interface TestViewController ()<MTGBannerAdViewDelegate>
@property(nonatomic,strong) MTGBannerAdView *bidBannerView;
@end
@implementation TestViewController
- (void)viewDidLoad {
[super viewDidLoad];
if (_bidBannerView == nil) {
_bannerAdView = [[MTGBannerAdView alloc]initBannerAdViewWithAdSize:size placementId:kBannerPlacementId unitId:kBannerUnitID rootViewController:self];
_bidBannerView.delegate = self;
_bidBannerView.autoRefreshTime = 0;
_bidBannerView.hidden = YES;
[self.view addSubview:_bidBannerView];
[_bidBannerView loadBannerAdWithBidToken:self.bidToken];
}
}
#pragma mark -- MTGBannerAdViewDelegate
- (void)adViewLoadSuccess:(MTGBannerAdView *)adView {
_bidBannerView.hidden = NO;
[self log:[NSString stringWithFormat:@"%@",NSStringFromSelector(_cmd)]];
}
- (void)adViewLoadFailedWithError:(NSError *)error adView:(MTGBannerAdView *)adView {
[self log:[NSString stringWithFormat:@"Load Error:%@",error.debugDescription]];
}
- (void)adViewWillLogImpression:(MTGBannerAdView *)adView {
[self log:[NSString stringWithFormat:@"%@",NSStringFromSelector(_cmd)]];
}
- (void)adViewDidClicked:(MTGBannerAdView *)adView {
[self log:[NSString stringWithFormat:@"%@",NSStringFromSelector(_cmd)]];
}
...
...
@end
当MTGSDK出价赢得竞价后,下一步是使用loadWithBidToken 方法来请求广告。
此部分与普通请求广告很相似,只有一处不同,您需要调用loadWithBidToken来请求广告,而不是调用loadAd 方法。其中对于bidToken,客户端到服务端集成方式中您可以通过这样来获取:bidResponse.bidToken,若您使用服务端到服务端集成方式需将Mintegral返回的bidid作为bidtoken传入进行广告加载 Object:BidResponse 。
Delegate的回调方法与普通请求广告是一样的。
Sample Code:
Copy #import "TestViewController.h"
#import <MTGSDK/MTGSDK.h>
#import <MTGSDK/MTGNativeAdManager.h>
#import <MTGSDKBidding/MTGBiddingRequest.h>
@interface TestViewController ()<MTGMediaViewDelegate,MTGBidNativeAdManagerDelegate>
@property (nonatomic, strong) MTGBidNativeAdManager *bidAdManager;
@end
@implementation TestViewController
- (void)viewDidLoad {
[super viewDidLoad];
if (_bidAdManager == nil) {
_bidAdManager = [[MTGBidNativeAdManager alloc] initWithPlacementId:KNativePlacementId unitID:KNativeUnitID presentingViewController:nil];
_bidAdManager.delegate = self;
[self.bidAdManager loadWithBidToken:self.bidToken];
}
}
#pragma mark AdManger delegate
- (void)nativeAdsLoaded:(NSArray *)nativeAds nativeManager:(nonnull MTGNativeAdManager *)nativeManager {
// load succesful
}
- (void)nativeAdsFailedToLoadWithError:(NSError *)error nativeManager:(nonnull MTGNativeAdManager *)nativeManager {
}
...
...
@end
当MTGSDK出价赢得竞价后,下一步是使用loadVideoWithBidToken 方法来请求广告。
此部分与普通请求广告很相似,只有一处不同,您需要调用loadVideoWithBidToken 来请求广告,而不是调用loadVideoAd 方法。其中对于bidToken,客户端到服务端集成方式中您可以通过这样来获取:bidResponse.bidToken,若您使用服务端到服务端集成方式需将Mintegral返回的bidid作为bidtoken传入进行广告加载Object:BidResponse 。
监听器的回调方法与普通请求广告对象监听器是一样的。
Sample code:
Copy #import <MTGSDKReward/MTGBidRewardAdManager.h>
#import <MTGSDK/MTGSDK.h>
#import <MTGSDKBidding/MTGBiddingRequest.h>
@interface MTGRewardVideoViewController ()
<MTGRewardAdLoadDelegate,MTGRewardAdShowDelegate>
- (void)viewDidLoad {
...
}
- (void)loadVideo{
//This method is used to open RewardPlus for RewardVideo,if you need,please set this before loadVideo,defalue NO.
//[MTGBidRewardAdManager sharedInstance].openRewardPlus = YES;
[[MTGBidRewardAdManager sharedInstance] loadVideoWithBidToken:self.bidToken placementId:kRewardPlacementId unitId:KRewardUnitID delegate:self];
- }
- (void)showVideo{
//Check whether video has been downloaded successfully before displaying ad
if ([[MTGBidRewardAdManager sharedInstance] isVideoReadyToPlayWithPlacementId:kRewardPlacementId unitId:KRewardUnitID]) {
[[MTGBidRewardAdManager sharedInstance] showVideoWithPlacementId:kRewardPlacementId unitId:KRewardUnitID withRewardId:KRewardID userId:@"" delegate:self viewController:self];
}
}
#pragma mark - MTGRewardAdShowDelegate Delegate
//Show Reward Video Ad Success Delegate
- (void)onVideoAdShowSuccess:(nullable NSString *)placementId unitId:(NSString *)unitId {
[self log:[NSString stringWithFormat:@"unitId = %@, show success", unitId]];
}
//Show Reward Video Ad Failed Delegate
- (void)onVideoAdShowFailed:(nullable NSString *)placementId unitId:(NSString *)unitId withError:(NSError *)error {
[self log:[NSString stringWithFormat:@"unitId = %@, show failed, error: %@", unitId, error]];
}
...
...
...
@end
当MTGSDK出价赢得竞价后,下一步是使用loadVideoWithBidToken 方法来请求广告。
此部分与普通请求广告很相似,只有一处不同,您需要调用loadVideoWithBidToken 来请求广告,而不是调用loadVideoAd 方法。其中对于bidToken,客户端到服务端集成方式中您可以通过这样来获取:bidResponse.bidToken,若您使用服务端到服务端集成方式需将Mintegral返回的bidid作为bidtoken传入进行广告加载Object:BidResponse 。
监听器的回调方法与普通请求广告对象监听器是一样的。
Sample code:
Copy #import "MTGInsterstialVideoViewController.h"
#import <MTGSDKInterstitialVideo/MTGBidInterstitialVideoAdManager.h>
#import <MTGSDKBidding/MTGBiddingRequest.h>
#import <MTGSDK/MTGSDK.h>
@interface MTGInsterstialVideoViewController ()<MTGBidInterstitialVideoDelegate>
@property (nonatomic,strong) MTGBidInterstitialVideoAdManager *ivBidAdManager;
@end
@implementation MTGInsterstialVideoViewController
- (void)viewDidLoad {
[super viewDidLoad];
...
...
}
- (void)loadVideo{
if (!_ivBidAdManager ) {
_ivBidAdManager = [[MTGBidInterstitialVideoAdManager alloc]initWithPlacementId:KInterstitialVideoPlacementId unitId:KInterstitialVideoUnitID delegate:self];
_ivBidAdManager.delegate = self;
}
[_ivBidAdManager loadAdWithBidToken:@"your bidToken"];
}
- (void)showVideo{
if ([_ivBidAdManager isVideoReadyToPlayWithPlacementId:KInterstitialVideoPlacementId unitId:KInterstitialVideoUnitID]) {
[_ivBidAdManager showFromViewController:self];
}
}
#pragma mark - Interstitial Delegate Methods
- (void) onInterstitialAdLoadSuccess:(MTGInterstitialVideoAdManager *_Nonnull)adManager{
[self log:NSStringFromSelector(_cmd)];
}
- (void) onInterstitialVideoLoadSuccess:(MTGInterstitialVideoAdManager *_Nonnull)adManager{
[self log:NSStringFromSelector(_cmd)];
}
...
...
@end
当MTGSDK出价赢得竞价后,下一步是请求广告。
此部分与普通请求广告很相似,只有一处不同,您需要调用 preloadWithBidToken 或 loadAndShowXXXbidToken来请求广告,而不是调用 preload 或 loadAndShowXXX 方法。其中对于bidToken,客户端到服务端集成方式中您可以通过这样来获取:bidResponse.bidToken,若您使用服务端到服务端集成方式需将Mintegral返回的bidid作为bidtoken传入进行广告加载Object:BidResponse 。
监听器的回调方法与普通请求广告对象监听器是一样的。
Sample code:
Copy #import "MTGSplashAdViewController.h"
#import <MTGSDKSplash/MTGSplashAD.h>
#import <MTGSDK/MTGSDK.h>
#import <MTGSDKBidding/MTGBiddingSplashRequestParameter.h>
#import <MTGSDKBidding/MTGBiddingRequest.h>
@interface MTGSplashAdViewController () <MTGSplashADDelegate>
@property (nonatomic, strong) MTGSplashAD *splashAD;
@property (nonatomic, strong) UISwitch *useCache;
@property (nonatomic, strong) UISwitch *useLogo;
@property (nonatomic, strong) UISwitch *skip;
@end
@implementation MTGSplashAdViewController
- (void)createSplashAD {
if (self.useLogo.on) {
self.splashAD = [[MTGSplashAD alloc]initWithPlacementID:kSplashPlacementId unitID:kSplashUnitID countdown:10 allowSkip:self.skip.on customViewSize:CGSizeMake(200, 95) preferredOrientation:0];
} else {
self.splashAD = [[MTGSplashAD alloc]initWithPlacementID:kSplashPlacementId unitID:kSplashUnitID countdown:10 allowSkip:self.skip.on customViewSize:CGSizeZero preferredOrientation:0];
}
self.splashAD.delegate = self;
if (self.useCache.on) {
self.splashAD.useCache = MTGBoolYes;
}
UIImage *splashImage = [UIImage imageNamed:@"bgx"];
self.splashAD.backgroundImage = splashImage;
}
//Load Video
- (IBAction)preloadButtonAction:(id)sender
{
[self createSplashAD];
[self log:@"bid splash ad is loading"];
[self.splashAD preloadWithBidToken:self.bidToken];
}
//isReady
- (void)isReadyButtonAction:(UIButton *)button {
[self createSplashAD];
BOOL ready = [self.splashAD isBiddingADReadyToShow];
[self log:[NSString stringWithFormat:@"isReady : %@", ready ? @"true" : @"false"]];
}
//Show Video
- (IBAction)showButtonAction:(id)sender
{
[self createSplashAD];
UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
UIView *logoView = nil;
if (self.useLogo.on) {
logoView = [self logoView];
}
[self.splashAD showBiddingADInKeyWindow:keyWindow customView:logoView];
}
//LoadNShow
- (void)LoadNShowButtonAction:(UIButton *)btn {
[self createSplashAD];
UIView *logoView = nil;
if (self.useLogo.on) {
logoView = [self logoView];
}
[self log:@"bid splash ad is loading"];
UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
[self.splashAD loadAndShowInKeyWindow:keyWindow customView:logoView bidToken:self.bidToken timeout:5000];
}
//logoView
- (UIView *)logoView {
UIImageView *logo = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"logo"]];
logo.frame = CGRectMake(0, 0, 100, 100);
return logo;
}
#pragma mark - MTGSplashADDelegate
- (void)splashADPreloadSuccess:(MTGSplashAD *)splashAD {
[self log:[NSString stringWithFormat:@"unitId = %@, preload success", splashAD.unitID]];
}
- (void)splashADPreloadFail:(MTGSplashAD *)splashAD error:(NSError *)error {
[self log:[NSString stringWithFormat:@"unitId = %@, preload error : %@", splashAD.unitID, error]];
}
// 开屏广告素材加载成功 / 失败
- (void)splashADLoadSuccess:(MTGSplashAD *)splashAD {
[self log:[NSString stringWithFormat:@"unitId = %@, load success", splashAD.unitID]];
}
- (void)splashADLoadFail:(MTGSplashAD *)splashAD error:(NSError *)error {
[self log:[NSString stringWithFormat:@"unitId = %@, load error : %@", splashAD.unitID, error]];
}
// 展示成功 / 失败
- (void)splashADShowSuccess:(MTGSplashAD *)splashAD {
[self log:[NSString stringWithFormat:@"unitId = %@, show success", splashAD.unitID]];
}
- (void)splashADShowFail:(MTGSplashAD *)splashAD error:(NSError *)error {
[self log:[NSString stringWithFormat:@"unitId = %@, show error : %@", splashAD.unitID, error]];
}
// 进入后台
- (void)splashADDidLeaveApplication:(MTGSplashAD *)splashAD {
[self log:[NSString stringWithFormat:@"unitId = %@, leave app", splashAD.unitID]];
}
// 点击
- (void)splashADDidClick:(MTGSplashAD *)splashAD {
[self log:[NSString stringWithFormat:@"unitId = %@, did click", splashAD.unitID]];
}
// 关闭
- (void)splashADWillClose:(MTGSplashAD *)splashAD {
[self log:[NSString stringWithFormat:@"unitId = %@, ad will close", splashAD.unitID]];
}
- (void)splashADDidClose:(MTGSplashAD *)splashAD {
[self log:[NSString stringWithFormat:@"unitId = %@, ad closed", splashAD.unitID]];
}
// countdown
- (void)splashAD:(MTGSplashAD *)splashAD timeLeft:(NSUInteger)time {
[self log:[NSString stringWithFormat:@"unitId = %@, ad countdown : %@", splashAD.unitID, @(time)]];
}
@end
3.2.6 获取buyerUID(可选项)
注:该步骤主要在服务端到服务端对接模式中用到,若开发者采用客户端到服务端对接模式则无需获取buyeruid。获取并使用该参数有助于更好地让Mintegral算法更好地进行广告优化,但本步骤不是强制的
通过调用静态方法[MTGBiddingSDK buyerUid]来获取Mitegral用户标识buyerUID,并将这个buyerUID告知你自己的服务端,用于执行服务端的竞价请求Object:User ,建议您在每次初始化应用后重新获取buyerUID。
四、服务端OpenRTB竞价协议说明
若开发者想通过服务端直接与Mintegral服务器进行竞价,需要基于OpenRTB 2.5的协议要求进行请求。
4.1 请求参数
请求和返回都是使用基于OpenRTB 2.5的协议做局部自定义调整,使用json的格式描述,需要在Http Header中增加 openrtb:2.5 的键值对
如果使用Curl测试可以使用 -H "openrtb:2.5"
http请求方式: POST
4.1.1 Object:BidRequest
Imp object,标记一次广告展示;MTG仅支持一次请求包含一个imp object
integer; optional;default 1
4.1.2 Object:Imp
广告版位ID,您可以在Mintegral开发者后台“版位&广告单元”页面查询到该ID。
string;optional;default "USD"
4.1.2.1 Object:Imp.banner
4.1.2.2 BidRequest.imp.ext.skadn
支持SKAdNetwork的版本。
通常为“ 2.0”或更高。
取决于OS版本和SDK版本。
苹果应用商店中发布者应用的ID。
与BidRequest.app.bundle一致
发布者APP的info.plist中与DSP
相关的SKAdNetworkIdentifier的子集。
["SKAdNetwork1.skadnetwork",
" SKAdNetwork2.skadnetwork"]
4.1.3 Object:App
自定义object,主要包括orientation字段
4.1.3.1 Object:Orientation Ext
4.1.4 Object:Device
设备语言;采用ISO-639-1-alpha-2标准
4.1.5 Object:User
4.2 返回数据
以下列举了返回数据结构的各类参数
4.2.1 Object:BidResponse
MTG返回的后续竞价胜出后用于加载广告的token id;
4.2.1.1 Object:SeatBid
4.2.1.1.1 Object:Bid
返回bidrequest.imp.id;标识对某个具体的imp object出价;
4.2.1.1.1.1 Object:BidResponse.seatbid.bid.ext.skadn
SKAdNetwork的版本。
必须为2.0或更高。
签名中使用的广告网络标识符。
应与请求中skadnetids数组中的一项匹配
"network":"dsp1.skadnetwork"
与Apple规范兼容的广告系列ID。
从2.0开始,应为1到100之间的整数,表示为字符串
苹果应用商店中广告客户应用的ID。
应该匹配BidResponse.seatbid.bid.bundle
每个广告响应唯一的ID。
有关正确的UUID格式要求,请参阅Apple文档。
"nonce": "beeeb65e-b3de-02420004"
苹果应用商店中发布者应用的ID。
应该匹配BidRequest.imp.ext.skad.sourceapp
"timestamp": "1594406341"
"signature": "MEQCIEQZRRyMyUXg=="
4.3 示例
4.3.1 请求示例
Copy {
"user": {
"buyeruid": "NnvFiAV2GaNwx3foiZTTinvFWVRPiUNwNnlMNARPinVMxnxj6deIkjx7xTheiUN2HFHA4+f6LkxIkjx7xTheiUN2HFH0Lb5M+FQ367cMh7eQ67QNL7K/HnjMWafIG+ewL5I2WUN/idMBfaiF4ajeiU5InkK1LkesDZI2WUvlp7QNL7K/HnslN2S5R7QNL7K/HZSyVBvei5Ie+ARlY7Q8HZSfDkiln2ilko3lN+SMY75+HkzWL+NXfUvTWUi/fZvEZTtVnVMsR7euLFVlxF5ULFIuRj2XDrQsHZIefVRBiaR="
},
"id": "5cebee04c6c1e276cc8b2e8x",
"imp": [{
"id": "1",
"tagid": "21316",
"bidfloor": 0.1,
"bidfloorcur": "USD",
"ext": {
"skadn": {
"version": "2.0",
"sourceapp": "880047117",
"skadnetids": [
"cdkw7geqsh.skadnetwork",
"qyJfv329m4.skadnetwork"
]
}
},
"banner": {
"w": "bannerWidth",
"h": "bannerHeight",
}
}],
"app": {
"id": "92763",
"ext": {
"orientation": 0
},
"ver": "5.4.0"
},
"device": {
"ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_1_2 like Mac OS X) AppleWebKit/604.3.5 (KHTML, like Gecko) Mobile/15B202",
"ip": "39.109.124.93",
"devicetype": 4,
"make": "apple",
"model": "iPhone10,3",
"os": "ios",
"osv": "11.1.2",
"language": "zh-Hans-US",
"carrier": "",
"connectiontype": 2,
"w": 2436,
"h": 1125,
"mccmnc": "460-02",
"ifa": "A0635584-FCB1-4106-B924-A80C29150E4D"
},
"at": 1,
"tmax": 150
}
4.3.2返回结果示例
Copy {
"id": "5cebee04c6c1e276cc8b2e8x",
"seatbid": [{
"bid": [{
"id": "89e3a366-5915-4b3c-87cf-afbf34b0857f",
"impid": "1",
"price": 107.2339653968811,
"lurl": "https://test-adnet.rayjump.com/loss?td=inRTfacIGnRbfUfIiAV9iaJIL7zIYbSQYrcML+euYgxQhgfTL+xuDke6JrQ3HkKILkKA672u+AV/fo9M6aV/fo9M6jtW6aiPidMe6aSIfgM9GkVADniFf0T2Gnj2Wnx0iFiwGaJUH02tHrzriAx0ial2fFD=",
"nurl": "https://test-adnet.rayjump.com/win?td=inRTfacIGnRbfUfIiAV9iaJIL7zIYbSQYrcML+euYgxQhgfTL+xuDke6JrQ3HkKILkKA672u+AV/fo9M6aV/fo9M6jtW6aiPidMe6aSIfgM9GkVADniFf0T2Gnj2Wnx0iFiwGaJUH02tHrzriAx0ial2fFD=",
"ext": {
"skadn": {
"version": "2.0",
"network": "cdkw7geqsh.skadnetwork",
"campaign": "45",
"itunesitem": "123456789",
"nonce": "473b1a16-b4ef-43ad-9591-fcf3aefa82a7",
"sourceapp": "880047117",
"timestamp": "1594406341",
"signature": "MEQCIEQlmZRNfYzKBSE8QnhLTIHZZZWCFgZpRqRxHss65KoFAiAJgJKjdrWdkLUOCCjuEx2RmFS7daRzSVZRVZ8RyMyUXg=="
}
}
}
]
}],
"bidid": "89e3a366-5915-4b3c-87cf-afbf34b0857f",
"cur": "USD"
}
五、错误码说明
http extract filter param is not http.Request"
S2S bid request data empty
req_param_filter input error
render bid request data error
Bid Request unit InValidate
Bid Request App InValidate
Buyeruid data is invalidate
Bid Request mtg sdk version too low
area target filter input is error
query netacuity server error
bid in unit and country code blacklist
user agent data filter input error
replace brand model filter input error
replaceBrand params error
render core data filter input error
Unit ad num set none error
iv orientation invalidate error
iv recallnet invalidate error
renderScreenSize input is error
current app is disable header bidding
illegal sdk version for Google play
build as request filter input is invalidate
compose ad server request error
traffic sample filter input error
bid adx filter input is error
compose adx http request error
afterbid request is not 200
bid adx decode resp error
real time bidding price error
bid cache filter input error
format output filter input error