Skip to main content

iOS 开屏广告接入

请注意:从V2.7版本开始,开屏广告实现方式由原来的VC实现改为View实现,如果您从老版本升级到V2.7及以上上版本,并且接入了开屏广告,请重新按照下面文档接入开屏广告。

加载广告并注册回调#

开屏广告加载是通过调用KLNSplashAd类的静态方法loadWithRequest: completionHandler:完成的。该方法需要两个参数,一是KLNSplashAdRequest对象,二是加载成功或者失败的回调Block。

加载成功得到KLNSplashAd实例后,注册 id<KLNSplashAdDelegate> delegate 属性,KLNSplashAdDelegate 协议暴露了广告曝光、广告点击、广告关闭等事件回调。

开屏请求参数类KLNSplashAdRequest主要接口#

类名属性说明
KLNSplashAdRequestposId广告位置Id,初始化函数initWithPosId:必填参数
timeout开屏超时时长,单位秒,不设置默认5s。建议设置3s以上
adSize广告请求尺寸。预留参数,目前SDK暂不支持通过设置adSize来请求相应尺寸广告。不过KLNSplashAd的adView属性会使用adSize来创建view的宽和高,不设置默认为屏幕宽和高

开屏广告类KLNSplashAd主要接口#

类名属性&&方法说明
KLNSplashAd delegateKLNSplashAdDelegate广告事件回调对象。接入方可以实现该属性获取广告曝光、点击、关闭等事件
viewController开发者传入的用来present目标页的ViewController,必传
adTyp广告类型。 未知模版 KLNSplashAdTypeUnknown = 1, 竖版9:16开屏大图 KLNSplashAdTypeVerImage = 2001, 竖版9:16开屏视频 KLNSplashAdTypeVerVideo = 2002,
hideSkipButton是否隐藏SDK跳过按钮,如果隐藏,接入方必须自定义跳过按钮。默认为NO。请注意:请在获取adView之前设置改属性。自定义跳过按钮时,SDK内部不会有倒计时逻辑,需要接入方去实现
adView广告view
promotedType返回广告的推广类型:2=下载广告; 3=网页推广广告【2.10.1版本新增】
requestId广告请求ID
请注意:从V2.11版本新增该字段,接入方可以拼接requestId和creativeID唯一标记一个广告
creativeID广告创意ID
请注意:从V2.11版本新增该字段,接入方可以拼接requestId和creativeID唯一标记一个广告
+loadWithRequest:completionHandler:加载开屏广告方法。参数:request 开屏广告请求对象;completionHandler 广告加载结果回调(成功/失败)。请注意:回调非线程安全。
-removeSplashAd关闭广告时,建议先调用该方法释放资源。比如停止倒计时,自定义跳过按钮时停止视频播放。请注意:在主线程调用该方法。

广告事件回调KLNSplashAdDelegate#

类名方法名说明
KLNSplashAdDelegatekln_splashAdWillExpose:广告曝光回调。业务方可以通过实现该方法,统计曝光量(对账)
kln_splashAdDidClick:广告点击回调。业务方可以通过实现该方法,统计点击量(对账)
kln_splashAdClosed:广告关闭回调。当用户点击广告、点击SDK跳过按钮,SDK倒计结束时都会回调该方法,请在此回调方法中进行广告对象的移除操作
kln_splashAdClickSkip:当用户点击SDK跳过按钮时会触发此回调
kln_splashAdDidCloseOtherController:interactionType:广告跳转到其他控制器时,控制器被关闭时调用。
interactionType参数:KLNInteractionType枚举类型,包括Appstore/网页/视频详情页等。
请注意:从V2.8.0版本开始支持该方法回调。

以下示例展示了如何加载 KLNSplashAd,具体请参照Demo

KLNSplashAdRequest * request = [[KLNSplashAdRequest alloc] initWithPosId:[self posId]];
request.timeout = 5;
request.adSize = self.navigationController.view.frame.size;
__weak typeof(self)weakSelf = self;
[KLNSplashAd loadWithRequest:request completionHandler:^(KLNSplashAd * _Nullable splashAd, NSError * _Nullable error) {
[weakSelf.splashAd.adView removeFromSuperview];
[weakSelf.splashAd removeSplashAd];
weakSelf.splashAd = nil;
if (splashAd) {
[weakSelf reportBidding:splashAd];
weakSelf.splashAd = splashAd;
weakSelf.splashAd.delegate = weakSelf;
weakSelf.splashAd.viewController = weakSelf;
weakSelf.splashAd.hideSkipButton = NO;
weakSelf.splashAd.adView.frame = CGRectMake(0, 0, request.adSize.width, request.adSize.height);
[weakSelf.navigationController.view addSubview: weakSelf.splashAd.adView];
}
}];

展示广告#

由于开屏广告是以view的形式给到接入方,所以接入方可以按照自己情况自定义开屏广告,比如全屏开屏广告、自定义跳过广告按钮、半屏广告+自定义App Logo,下面举例说明接入方式,具体请参见Demo。

全屏开屏广告#

- (void)_onFullScreenBtnClick {
KLNSplashAdRequest * request = [[KLNSplashAdRequest alloc] initWithPosId:[self posId]];
request.timeout = 5;
request.adSize = self.navigationController.view.frame.size;
__weak typeof(self)weakSelf = self;
[KLNSplashAd loadWithRequest:request completionHandler:^(KLNSplashAd * _Nullable splashAd, NSError * _Nullable error) {
[weakSelf.splashAd.adView removeFromSuperview];
[weakSelf.splashAd removeSplashAd];
weakSelf.splashAd = nil;
if (splashAd) {
[weakSelf reportBidding:splashAd];
weakSelf.splashAd = splashAd;
weakSelf.splashAd.delegate = weakSelf;
weakSelf.splashAd.viewController = weakSelf;
weakSelf.splashAd.hideSkipButton = NO;
weakSelf.splashAd.adView.frame = CGRectMake(0, 0, request.adSize.width, request.adSize.height);
[weakSelf.navigationController.view addSubview: weakSelf.splashAd.adView];
}
}];
}
- (void)kln_splashAdWillExpose:(KLNSplashAd *)ad {
KLNDemoLog(@"🌹开屏广告曝光 ad:%@", ad);
}
- (void)kln_splashAdDidClick:(KLNSplashAd *)ad {
KLNDemoLog(@"🌹开屏广告点击 ad:%@", ad);
}
- (void)kln_splashAdClosed:(KLNSplashAd *)ad {
KLNDemoLog(@"🌹开屏广告关闭 ad:%@", ad);
[self.splashAd.adView removeFromSuperview];
[self.splashAd removeSplashAd];
self.splashAd = nil;
}
- (void)kln_splashAdClickSkip:(KLNSplashAd *)ad {
KLNDemoLog(@"🌹开屏广告跳过 ad:%@", ad);
}

自定义跳过广告按钮#

接入方可以自行实现跳过按钮的样式及相关跳转逻辑。

请注意:接入方需要在获取adView之前把KLNSplashAd对象的hideSkipButton属性设置为YES,然后自定义跳过按钮。

- (void)_onFullScreenAndCustomSkipBtnClick {
KLNSplashAdRequest * request = [[KLNSplashAdRequest alloc] initWithPosId:[self posId]];
request.timeout = 5;
request.adSize = self.navigationController.view.frame.size;
__weak typeof(self)weakSelf = self;
[KLNSplashAd loadWithRequest:request completionHandler:^(KLNSplashAd * _Nullable splashAd, NSError * _Nullable error) {
[weakSelf _stopTimer];
[weakSelf.splashAd.adView removeFromSuperview];
[weakSelf.splashAd removeSplashAd];
weakSelf.splashAd = nil;
if (splashAd) {
[weakSelf reportBidding:splashAd];
weakSelf.splashAd = splashAd;
weakSelf.splashAd.delegate = weakSelf;
weakSelf.splashAd.viewController = weakSelf;
//自定义跳过按钮时,需要把hideSkipButton置为YES
weakSelf.splashAd.hideSkipButton = YES;
weakSelf.splashAd.adView.frame = CGRectMake(0, 0, request.adSize.width, request.adSize.height);
UIButton *customSkipButton = [UIButton buttonWithType:UIButtonTypeCustom];
customSkipButton.titleLabel.font = [UIFont systemFontOfSize:16];
customSkipButton.backgroundColor = [UIColor colorWithWhite:0 alpha:0.9];
customSkipButton.layer.cornerRadius = 8;
[customSkipButton setTitle:@"跳过广告" forState:UIControlStateNormal];
[customSkipButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
customSkipButton.contentEdgeInsets = UIEdgeInsetsMake(0, 12, 0, 24);
customSkipButton.titleEdgeInsets = UIEdgeInsetsMake(0, 0, 0, -12);
[customSkipButton addTarget:weakSelf action:@selector(_onSkipButtonClick) forControlEvents:UIControlEventTouchUpInside];
weakSelf.customSkipButton = customSkipButton;
CGFloat adViewHei = weakSelf.splashAd.adView.frame.size.height;
CGFloat safeBottom = 30;
if (@available(iOS 11.0, *)) {
safeBottom = weakSelf.view.safeAreaInsets.bottom;
} else {
// Fallback on earlier versions
}
if (safeBottom < 0.1) {
safeBottom = 30;
}
CGFloat wid = 130;
CGFloat hei = 36;
customSkipButton.frame = CGRectMake(16, adViewHei - hei - safeBottom, wid, hei);
[weakSelf.splashAd.adView addSubview:customSkipButton];
[weakSelf.navigationController.view addSubview: weakSelf.splashAd.adView];
if (weakSelf.splashAd.adType == KLNSplashAdTypeVerImage) {
[weakSelf _startTimerWithTotalTime:5];
} else if(weakSelf.splashAd.adType == KLNSplashAdTypeVerVideo) {
[weakSelf _startTimerWithTotalTime:10];
} else {
[weakSelf _startTimerWithTotalTime:5];
}
}
}];
}
- (void)_stopTimer {
if (self.countdownTimer) {
[self.countdownTimer invalidate];
self.countdownTimer = nil;
}
}
- (void)_startTimerWithTotalTime:(NSTimeInterval)total {
[self _stopTimer];
NSTimeInterval beginTime = [NSDate timeIntervalSinceReferenceDate];
__weak typeof(self)weakSelf = self;
self.countdownTimer = [NSTimer klnDemo_scheduledTimerWithTimeInterval:0.5 block:^{
NSTimeInterval nowTime = [NSDate timeIntervalSinceReferenceDate];
if (nowTime >= beginTime + total) {
// 曝光时长完成
[weakSelf.customSkipButton setTitle:@"跳过广告" forState:UIControlStateNormal];
[weakSelf _stopTimer];
[weakSelf _onSkipButtonClick];
return;
}
// update text display
int left = (int)ceilf(beginTime + total - nowTime);
NSString *discount = [NSString stringWithFormat:@"跳过广告 %i", left];
[weakSelf.customSkipButton setTitle:discount forState:UIControlStateNormal];
} repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.countdownTimer forMode:NSRunLoopCommonModes];
[self.countdownTimer fire];
}
- (void)_onSkipButtonClick {
[self _stopTimer];
[self.splashAd.adView removeFromSuperview];
[self.splashAd removeSplashAd];
self.splashAd = nil;
}
- (void)kln_splashAdWillExpose:(KLNSplashAd *)ad {
KLNDemoLog(@"🌹开屏广告曝光 ad:%@", ad);
}
- (void)kln_splashAdDidClick:(KLNSplashAd *)ad {
KLNDemoLog(@"🌹开屏广告点击 ad:%@", ad);
[self _stopTimer];
}
- (void)kln_splashAdClosed:(KLNSplashAd *)ad {
KLNDemoLog(@"🌹开屏广告关闭 ad:%@", ad);
[self _stopTimer];
[self.splashAd.adView removeFromSuperview];
[self.splashAd removeSplashAd];
self.splashAd = nil;
}
- (void)kln_splashAdClickSkip:(KLNSplashAd *)ad {
KLNDemoLog(@"🌹开屏广告跳过 ad:%@", ad);
}

半屏开屏广告#

接入方可以实现半屏开屏广告,比如实现半屏开屏广告+底部logo view。

- (void)_onHalfScreenAndCustomAppLogoBtnClick {
KLNSplashAdRequest * request = [[KLNSplashAdRequest alloc] initWithPosId:[self posId]];
request.timeout = 5;
CGFloat wid = self.navigationController.view.frame.size.width;
CGFloat hei = self.navigationController.view.frame.size.height * 0.8;
request.adSize = CGSizeMake(wid, hei);
__weak typeof(self)weakSelf = self;
[KLNSplashAd loadWithRequest:request completionHandler:^(KLNSplashAd * _Nullable splashAd, NSError * _Nullable error) {
[weakSelf.splashAd.adView removeFromSuperview];
[weakSelf.splashAd removeSplashAd];
weakSelf.splashAd = nil;
if (splashAd) {
[weakSelf reportBidding:splashAd];
weakSelf.splashAd = splashAd;
weakSelf.splashAd.delegate = weakSelf;
weakSelf.splashAd.viewController = weakSelf;
weakSelf.splashAd.hideSkipButton = NO;
UIView* bottomView = [[UIView alloc] initWithFrame:CGRectZero];
bottomView.backgroundColor = [UIColor whiteColor];
UIImageView *logoImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
logoImageView.image = [UIImage imageNamed:@"YKYLogo"];
[bottomView addSubview:logoImageView];
weakSelf.customBottomView = bottomView;
CGFloat adViewWid = request.adSize.width;
CGFloat adViewHei = request.adSize.height;
weakSelf.splashAd.adView.frame = CGRectMake(0, 0, adViewWid, adViewHei);
bottomView.frame = CGRectMake(0, adViewHei, adViewWid, weakSelf.navigationController.view.frame.size.height - adViewHei);
CGFloat logoImageViewWid = 128;
CGFloat logoImageViewHei = 85;
logoImageView.frame = CGRectMake((bottomView.frame.size.width - logoImageViewWid) / 2, (bottomView.frame.size.height - logoImageViewHei) / 2, logoImageViewWid, logoImageViewHei);
[weakSelf.navigationController.view addSubview:bottomView];
[weakSelf.navigationController.view addSubview:weakSelf.splashAd.adView];
}
}];
}

其他说明#

1)从V2.7版本开始,开屏广告实现方式由原来的VC实现改为View实现,如果您从老版本升级到V2.7及以上版本,并且接入了开屏广告,请重新按照本文档接入开屏广告。

2)目前开屏广告只支持竖屏,不支持横屏。

3)开屏广告返回的是一个view,客户端直接展示view即可。如果要在底部添加自身logo,需要缩小开屏广告的展示区域,建议开屏半屏广告的显示区域其高度大于屏幕高度的80%。

4)开屏广告请求的超时时间建议设置为3s以上,不设置默认为5s。

5)避免出现展示广告的父view/父window被提前释放或取错父view/父window的情况。