Admob-聚合广告接入

发表于2018-12-13
评论6 1.46w浏览

印象中,第一次接入Admob广告是在三年前,当时在一款消除类的游戏上,Android平台,仅仅是接入了Admob Interstitial插屏,那时候还并没有视频广告 

 

为了快速的在GP上线,体验Admob广告的流程,接入的很仓促,后来有好长的一段时间 没有关关注,有一次打开Admob后台看了有100多美元的收益,当时使用西联汇款结帐,拿着广告的收益,非常开心的请当时的同事们喝了北冰洋:) 

 

那次只有在Android平台接入,当时工具还是Eclipse,并且GooglePlayService并没有进行模块化分包,直接引用了一个非常大的full jar,现在GooglePlayService更加的模块化,可以按需引用入不同的Jar包到项目中来 

 

后来有很长一段时间没有再去接触广告,最近接手公司的项目,均是通过Admob进行聚合,以前我接过的聚合比如HeyZap,Fyber,Yomobi等等,SDK的变化更比技术更快 

 

聚合:可以理解为多家广告平台整合在一起,为了提高Fill Rate填充率,就是可观看广告的数量,也可以增加广告的种类,并提高广告的收益,如果我们只接入1,2家广告平台,用户就会经常看到重复的广告,会产生很多无效的观看和下载,影响整体的体验和收益 

 

不同的广告平台之间也需要设置优先级,类似的广告平台: 

Unity Ads,Vungle,AppLovin,Facebook,Chartboost等等这些比较常见的广告平台,都会被聚合到不同的第三方SDK当中,由产品去负责根据数据来进行具体的配置,具体可以参考广告收益数据指标相关的知识 

 

有些第三方的聚合平台为了减少程序员的工作量,会帮你将这些SDK加好,但每家SDK都会有bugfix的版本,所以要经常的关注这些更新的动态 ,剩下的只需要根据他们的文档 进行配置就好,但像Admob,需要由你来自己接入这些 

 

以前没有了解过Admob聚合上的工作,这次项目有需要,要接入国内某条公司的广告SDK,在这里记录一下 




 

进入Admob,点击中介,可以看到两栏,中介组和广告联盟,这是接入聚合广告的两种方式先看右边的广告联盟 



下拉列表中列出了很多已经 广泛应用的第三方平台广告,针对这种SDK,我们不需要做多少额外的操作,已经成为了广告联盟,直接 使用就好 

 

如果我要接的广告平台是新的,还没有加入到广告联盟,如何进行聚合的控制呢,比如这次要接入的某条的SDK,就还没有成为广告联盟,所以Google提供了另外一种叫自定义事件的形式(Adapter) 

 

 

1.首先接入Admob到项目中,保证Admob自身可以正常的拉取,显示广告,以及处理相应的回调,比如广告加载成功,显示广告,关闭广告等回调 

 

2.接入未加入广告联盟的第三方广告,这里的某条SDK,同1,也要保证SDK初始化显示加载等等一切正常 

 

3.在Admob后台中介组中创建第三方广告的配置,配置中要填写 Class Name类名和可选的参数 

如图: 




4.根据上面的文档 ,创建Banner/Interstitial/RewardedVideo 三种广告类型的自定义事件(Adapter)类,我这里仅是以IOS平台为例,所以创建的是.m的OC类,第3步填写的也是 

OC的类名,必须确保一致,因为Admob会去搜索这个类并调用 

 

5.使用Admob分配的测试Ad Unit 测试中介广告是否生效 

 

所有未加入广告联盟均需要通过这种自定义事件的形式接入,所以自定义事件是独立于第三方SDK的,大家接入的方式是一样的 

 

说得再通俗一点: 

 

你先把第三方广告SDK独立的接入到项目中,可以正常的完成初始化,拉取Fetch广告,能够正常的显示广告,广告在加载成功,准备/开始播放,播放结束,关闭等等 

行为的回调都能够处理完成,保证第三方SDK是正常的 

 

然后根据Google的文档创建自定义事件类,这个类需要去实现一些接口,在文档中有说明,在这些接口中,包括了比如广告的请求,显示,关闭等等,你去实现这些接口就可以了,把第三方SDK对应的实现放进去 

 

Admob在获取广告的时候,会读取你在Admob中介组中的配置,上面提到要配置Class Name,就是上面创建的自定义事件类,Admob会去项目中搜索这个类,并调用特定的方法,然后完成 

广告的拉取,显示,关闭等等操作 

 

如果Admob没有成功拉取到广告,Admob会读取配置的下一个中介,这里就是由优先级控制的,实现这些接口的目的 也是为了通知Admob我当前广告的状态,比如你第三方SDK成功的拉到取到了广告,但你在自定义事件类中忘记通过特定的接口去通知Admob你拉到广告了,那么Admob就会认为你拉取失败,转而去下一个中介配置中继续拉取其它第三方的广告,所以一定要注意通知Admob,这在下面会介绍到 

 

下面直接上代码: 

我会对接口进行说明:




看着蛮多的,其实就是一套固定的模板 

 

InterstitialCustEventAdapter:插屏广告自定义事件类 

RewardVideoCustomEventAdapter:视频广告自定义事件类 

BannerCustEventAdapter:这里并没有提供,具体可以参考上面的文档或说明,或是下面的github中的Sample 

 

 

照着Sample写一份即可 

 

 

上面xxxxVC类并不是自定义事件类的一部分,他仅是Admob请求广告的Sample,方便我们通过这个类去测试中介广告是否生效 

 

1.先看插屏自定义事件的实现: 

 

BUDIntersititialCustomEventAdapter.h: 

 

#import <Foundation/Foundation.h> 

#import <GoogleMobileAds/GoogleMobileAds.h> 

 
 

@interface BUDInterstitialCustomEventAdapter : NSObject<GADCustomEventInterstitial> 

 
 

@end 

 



Google规定插屏要实现GADCustomEventInterstitial协议 

 

这个协议中只有两个接口: 



- (void)requestInterstitialAdWithParameter:(NSString *GAD_NULLABLE_TYPE)serverParameter 

                                     label:(NSString *GAD_NULLABLE_TYPE)serverLabel 

                                   request:(GADCustomEventRequest *)request; 

 

 

- (void)presentFromRootViewController:(UIViewController *)rootViewController; 


 

第一个用于插屏广告的初始化,第二个用于插屏广告的显示 


BUDIntersititialCustEventAdapter.m: 

 


#import "BUDInterstitialCustomEventAdapter.h" 

#import <BUAdSDK/BUInterstitialAd.h> 

#import <BUAdSDK/BUSize.h> 

 
 

/// Constant for Sample Ad Network custom event error domain. 

static NSString *const customEventErrorDomain = @"com.google.CustomEvent"; 

 
 

@interface BUDInterstitialCustomEventAdapter ()<BUInterstitialAdDelegate> 

 
 

@property (nonatomicstrongBUInterstitialAd *interstitialAd; 

 
 

@end 

 
 

@implementation BUDInterstitialCustomEventAdapter 

@synthesize delegate; 

 
 

#pragma mark BUDInterstitialCustomEventAdapter implementation 

 
 

+ (Class<GADAdNetworkExtras>)networkExtrasClass { 

    // OPTIONAL: Create your own class implementing GADAdNetworkExtras and return that class type 

    // here for your publishers to use. This class does not use extras. 

    return Nil; 

 

 
 

- (void)requestInterstitialAdWithParameter:(NSString *)serverParameter 

                                     label:(NSString *)serverLabel 

                                   request:(GADCustomEventRequest *)request { 

     

    self.interstitialAd = [[BUInterstitialAd allocinitWithSlotID:serverParameter size:[BUSize sizeBy:BUProposalSize_DrawFullScreen]]; 

    self.interstitialAd.delegate = self; 

    [self.interstitialAd loadAdData]; 

 

 
 

/// Present the interstitial ad as a modal view using the provided view controller. 

- (void)presentFromRootViewController:(UIViewController *)rootViewController { 

    [self.interstitialAd showAdFromRootViewController:rootViewController]; 

 

 
 

#pragma mark SampleInterstitialAdDelegate implementation 

 
 

 
 

/** 

 点击插屏广告 回调该函数, 期间可能调起 AppStore ThirdApp WebView etc. 

 - Parameter interstitialAd: 产生该事件的 BUInterstitialAd 对象. 

 */ 

- (void)interstitialAdDidClick:(BUInterstitialAd *)interstitialAd { 

     NSLog(@"interstitialWillPresentScreen"); 

    [self.delegate customEventInterstitialWasClicked:self]; 

    [self.delegate customEventInterstitialWillLeaveApplication:self]; 

 

 
 

/** 

 关闭插屏广告 回调改函数,   {点击广告, 点击关闭} 

 - Parameter interstitialAd: 产生该事件的 BUInterstitialAd 对象. 

 */ 

- (void)interstitialAdDidClose:(BUInterstitialAd *)interstitialAd { 

    NSLog(@"interstitialAdDidClose"); 

    [self.delegate customEventInterstitialDidDismiss:self]; 

     [self.interstitialAd loadAdData]; 

     

 

 
 

/** 

 BUInterstitialAd 广告将要消失, 用户点击关闭按钮 

  

 - Parameter interstitialAd: 产生该事件的 BUInterstitialAd 对象. 

 */ 

- (void)interstitialAdWillClose:(BUInterstitialAd *)interstitialAd { 

     NSLog(@"interstitialAdWillClose"); 

    [self.delegate customEventInterstitialWillDismiss:self]; 

 

 
 

/** 

 BUInterstitialAd 广告加载成功 

  

 - Parameter interstitialAd: 产生该事件的 BUInterstitialAd 对象. 

 */ 

- (void)interstitialAdDidLoad:(BUInterstitialAd *)interstitialAd { 

     NSLog(@"interstitialAdDidLoad"); 

    [self.delegate customEventInterstitialDidReceiveAd:self]; 

 

 
 

/** 

 BUInterstitialAd 加载失败 

  

 - Parameter interstitialAd: 产生该事件的 BUInterstitialAd 对象. 

 - Parameter error: 包含详细是失败信息. 

 */ 

- (void)interstitialAd:(BUInterstitialAd *)interstitialAd didFailWithError:(NSError *)error { 

    NSLog(@"interstitialAd:didFailWithError"); 

    [self.delegate customEventInterstitial:self didFailAd:error]; 

 

 
 

 
 

/** 

 即将展示 插屏广告 

 - Parameter interstitialAd: 产生该事件的 BUInterstitialAd 对象. 

 */ 

- (void)interstitialAdWillVisible:(BUInterstitialAd *)interstitialAd { 

     NSLog(@"interstitialAdWillVisible"); 

    [self.delegate customEventInterstitialWillPresent:self]; 

 

 
 

 
 

@end 


 

这里又实现了另外一个协议BUInterstitialAdDelegate,这是第三广告提供的,里面包括了广告的加载,显示,关闭等回调,我们通过这些接口去通知Admob当前中介的状态 


@property (nonatomicstrongBUInterstitialAd *interstitialAd; 


 

这里定义了第三方广告平台的插屏对象,这里并不包含第三方广告平台的初始化工作,你可以放在应用启动的地方 

 

Admob会在请求Interstitial广告时,会调用requestInterstitialAdWithParameter方法 

完成播放广告的初始化工作,所以在这个接口中,我们要完成interstitialAd的请求操作 

 


 self.interstitialAd = [[BUInterstitialAd allocinitWithSlotID:serverParameter size:[BUSize sizeBy:BUProposalSize_DrawFullScreen]]; 

    self.interstitialAd.delegate = self; 

    [self.interstitialAd loadAdData]; 

 

 

完成插屏广告对象的初始化并开始拉取(LoadAdData) 

 

 

- (void)presentFromRootViewController 


插屏广告的显示,把第三方广告显示的代码写进去即可 

 

实现这两步是最基本的,其它接口是第三方广告平台的部分,就简要解释下: 

 

- (void)interstitialAdDidClick 



当我点击广告时的回调,在接口的内部要通知Admob,通知接口如下: 


[self.delegate customEventInterstitialWasClicked:self]; 

[self.delegate customEventInterstitialWillLeaveApplication:self]; 


 

- (void)interstitialAdDidClose 


当插屏广告关闭时回调,通知Admob: 


[self.delegate customEventInterstitialDidDismiss:self]; 


 

(这里需要注意一点,现在的广告在关闭后,都会自动在后台再次拉取,不需要我们手动的操作,所以这时候Admob会再次调用上面的requestInterstitialAdWithParameter接口,再去请求新的广告) 

 

- (void)interstitialAdWillClose 



广告将要消失,用户点击关闭按钮。通知Admob: 


[self.delegate customEventInterstitialWillDismiss:self]; 

 



- (void)interstitialAdDidLoad 


广告加载成功,通知Admob: 


[self.delegate customEventInterstitialDidReceiveAd:self]; 

 

- (void)interstitialAd:(BUInterstitialAd *)interstitialAd didFailWithError 


广告加载失败,通知Admob: 

 

[self.delegate customEventInterstitial:self didFailAd:error]; 


 

- (void)interstitialAdWillVisible 


即将展示插屏,通知Admob: 


[self.delegate customEventInterstitialWillPresent:self]; 


一定要在对应的接口中通知Admob,通知你当前广告的状态,这样Admob的流程才会完整,才会正常的执行后续的操作,具体哪些行为要通知Admob,可以参考上面给出的Google文档  

 

插屏的自定义事件介绍完了,这样Admob在请求插屏的时候,就会调用上面的自定义事件类,调用对应的接口,并通过第三方广告的回调,去通知Admob广告的行为,状态 

 

 

视频广告的自定义事件使用不同的接口,但流程上是一样的,代码就不贴了,我会将源码上传到网盘中 

 

这里需要注意的是,在Admob后台配置中介,可以带参数,这是可选 的,但建议使用,比如我更换了广告的ID,不需要更新客户端 ,具体获取参数的代码,插屏是直接 就带参数的,比如: 

 


 

- (void)requestInterstitialAdWithParameter:(NSString *)serverParameter 

                                     label:(NSString *)serverLabel 

                                   request:(GADCustomEventRequest *)request 

 



 

参数serverParameter 

 

视频广告自定义事件会有_rewardBasedVideoAdConnector对象,Parameter保存在里面的字典中,我们在setUp接口中(Google提供的接口,每次请求视频广告都会调用setUp) 

 

NSString* _id = [_rewardBasedVideoAdConnector.credentials objectForKey:@"parameter"];

 

 

有些啰嗦,如果工作中有这方面的需求,希望可以帮助到你 

 

下载地址: 

https://share.weiyun.com/5EtlCKs 

 

感谢您的阅读 ,如文中有误,欢迎指正,共同提高 

 

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引