-
Notifications
You must be signed in to change notification settings - Fork 24
3.4 原生模板、信息流广告
luyao edited this page Dec 21, 2021
·
1 revision
原生模板广告分为几个阶段:加载广告获得模板view,渲染广告模板,展示广告模板,需要注意的是,媒体需要持有SDK返回的view数组,否则view会自动释放,无法渲染成功。用户点击关闭按钮后,开发者需要从数组和视图中把关闭回调的view删除。
#import "DemoListFeedExpressViewController.h"
#import "CellBuilder.h"
#import "BYExamCellModel.h"
#import <EasyAdsSDK/EasyAdNativeExpress.h>
#import <EasyAdsSDK/EasyAdNativeExpressView.h>
#import "AdDataJsonManager.h"
@interface DemoListFeedExpressViewController () <UITableViewDelegate, UITableViewDataSource, EasyAdNativeExpressDelegate>
{
BOOL _isLoadAndShow;
BOOL _isShowLogView;
CGFloat _navAndStateBarHeight;
}
@property (strong, nonatomic) UITableView *tableView;
@property (strong,nonatomic) EasyAdNativeExpress *advanceFeed;
@property (nonatomic, strong) NSMutableArray *dataArrM;
@property (nonatomic, strong) NSMutableArray *arrViewsM;
@property (nonatomic, assign) BOOL isLoadAndShow;
@property (nonatomic, assign) BOOL isShowLogView;
@end
@implementation DemoListFeedExpressViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = @"信息流";
CGFloat statusHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
CGFloat navHeight = self.navigationController.navigationBar.frame.size.height;
_navAndStateBarHeight = navHeight + statusHeight;
self.textV.frame = CGRectMake(0,0 - 300, self.view.frame.size.width, 300);
self.dic = [[AdDataJsonManager shared] loadAdDataWithType:JsonDataType_nativeExpress];
UIBarButtonItem *rightBar = [[UIBarButtonItem alloc] initWithTitle:@"显示log信息" style:UIBarButtonItemStylePlain target:self action:@selector(showLogView)];
self.navigationItem.rightBarButtonItem = rightBar;
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
[self.view addSubview:_tableView];
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.bottom.equalTo(self.view);
make.height.equalTo(@(self.view.frame.size.height - 330));
}];
[_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"splitnativeexpresscell"];
[_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"nativeexpresscell"];
[_tableView registerClass:[ExamTableViewCell class] forCellReuseIdentifier:@"ExamTableViewCell"];
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.tableFooterView = [UIView new];
}
- (void)loadAd {
[super loadAd];
[self deallocAd];
[self loadAdWithState:AdState_Normal];
_isLoadAndShow = NO;
self.dataArrM = [NSMutableArray arrayWithArray:[CellBuilder dataFromJsonFile:@"cell01"]];
self.advanceFeed = [[EasyAdNativeExpress alloc] initWithJsonDic:self.dic viewController:self adSize:CGSizeMake(self.view.bounds.size.width, 0)];
self.advanceFeed.delegate = self;
[self.advanceFeed loadAd];
[self loadAdWithState:AdState_Loading];
}
- (void)showAd {
if (!self.advanceFeed || !self.isLoaded || self.dataArrM.count == 0 || self.arrViewsM.count == 0) {
[JDStatusBarNotification showWithStatus:@"请先加载广告" dismissAfter:1.5];
return;
}
[self showNativeAd];
}
- (void)loadAndShowAd {
[super loadAd];
[self deallocAd];
[self loadAdWithState:AdState_Normal];
_isLoadAndShow = YES;
self.dataArrM = [NSMutableArray arrayWithArray:[CellBuilder dataFromJsonFile:@"cell01"]];
self.advanceFeed = [[EasyAdNativeExpress alloc] initWithJsonDic:self.dic viewController:self adSize:CGSizeMake(self.view.bounds.size.width, 0)];
self.advanceFeed.delegate = self;
[self.advanceFeed loadAndShowAd];
[self loadAdWithState:AdState_Loading];
}
- (void)deallocAd {
self.advanceFeed = nil;
self.advanceFeed.delegate = nil;
self.isLoaded = NO;
[self.dataArrM removeAllObjects];
[self.arrViewsM removeAllObjects];
[self.tableView reloadData];
[self loadAdWithState:AdState_Normal];
}
// 信息流广告比较特殊, 渲染逻辑需要自行处理
- (void)showNativeAd {
for (NSInteger i = 0; i < self.arrViewsM.count; i++) {
EasyAdNativeExpressView *view = self.arrViewsM[i];
[view render];
[_dataArrM insertObject:self.arrViewsM[i] atIndex:1];
}
[self.tableView reloadData];
}
- (void)showLogView {
[UIView animateWithDuration:0.2 animations:^{
self.textV.frame = CGRectMake(0,((_isShowLogView = !_isShowLogView) ? _navAndStateBarHeight : -300 ), self.view.frame.size.width, 300);
self.navigationItem.rightBarButtonItem.title = _isShowLogView ? @"隐藏log信息":@"显示log信息";
}];
}
// MARK: ======================= EasyAdNativeExpressDelegate =======================
/// 广告数据拉取成功
- (void)easyAdNativeExpressOnAdLoadSuccess:(NSArray<EasyAdNativeExpressView *> *)views {
NSLog(@"广告拉取成功 %s", __func__);
self.arrViewsM = [views mutableCopy];
if (_isLoadAndShow) {
[self showNativeAd];
}
self.isLoaded = YES;
[self showProcessWithText:[NSString stringWithFormat:@"%s\r\n 广告拉取成功", __func__]];
[self loadAdWithState:AdState_LoadSucceed];
}
/// 广告曝光
- (void)easyAdNativeExpressOnAdShow:(EasyAdNativeExpressView *)adView {
NSLog(@"广告曝光 %s", __func__);
[self showProcessWithText:[NSString stringWithFormat:@"%s\r\n 广告曝光成功", __func__]];
}
/// 广告点击
- (void)easyAdNativeExpressOnAdClicked:(EasyAdNativeExpressView *)adView {
NSLog(@"广告点击 %s", __func__);
[self showProcessWithText:[NSString stringWithFormat:@"%s\r\n 广告点击", __func__]];
}
/// 广告渲染成功
/// 注意和广告数据拉取成功的区别 广告数据拉取成功, 但是渲染可能会失败
/// 广告加载失败 是广点通 穿山甲 mercury 在拉取广告的时候就全部失败了
/// 该回调的含义是: 比如: 广点通拉取广告成功了并返回了一组view 但是其中某个view的渲染失败了
/// 该回调会触发多次
- (void)easyAdNativeExpressOnAdRenderSuccess:(EasyAdNativeExpressView *)adView {
NSLog(@"广告渲染成功 %s %@", __func__, adView);
[self showProcessWithText:[NSString stringWithFormat:@"%s\r\n 广告渲染成功", __func__]];
[self.tableView reloadData];
}
/// 广告渲染失败
/// 注意和广告加载失败的区别 广告数据拉取成功, 但是渲染可能会失败
/// 广告加载失败 是广点通 穿山甲 mercury 在拉取广告的时候就全部失败了
/// 该回调的含义是: 比如: 广点通拉取广告成功了并返回了一组view 但是其中某个view的渲染失败了
/// 该回调会触发多次
- (void)easyAdNativeExpressOnAdRenderFail:(EasyAdNativeExpressView *)adView {
NSLog(@"广告渲染失败 %s %@", __func__, adView);
[self showProcessWithText:[NSString stringWithFormat:@"%s\r\n 广告渲染失败", __func__]];
[_dataArrM removeObject: adView];
[self.tableView reloadData];
}
/// 广告加载失败
/// 该回调只会触发一次
- (void)easyAdFailedWithError:(NSError *)error description:(NSDictionary *)description{
NSLog(@"广告展示失败 %s error: %@ 详情:%@", __func__, error, description);
[self showProcessWithText:[NSString stringWithFormat:@"%s\r\n 广告加载失败", __func__]];
[self showErrorWithDescription:description];
[self loadAdWithState:AdState_LoadFailed];
[self deallocAd];
}
/// 内部渠道开始加载时调用
- (void)easyAdSupplierWillLoad:(NSString *)supplierId {
NSLog(@"内部渠道开始加载 %s supplierId: %@", __func__, supplierId);
[self showProcessWithText:[NSString stringWithFormat:@"%s\r\n 内部渠道开始加载", __func__]];
}
/// 广告被关闭
- (void)easyAdNativeExpressOnAdClosed:(EasyAdNativeExpressView *)adView {
//需要从tableview中删除
NSLog(@"广告关闭 %s", __func__);
[_dataArrM removeObject: adView];
[self.tableView reloadData];
}
- (void)easyAdSuccessSortTag:(NSString *)sortTag {
NSLog(@"选中了 rule '%@' %s", sortTag,__func__);
[self showProcessWithText:[NSString stringWithFormat:@"%s\r\n 选中了 rule '%@' ", __func__, sortTag]];
}
// MARK: ======================= UITableViewDelegate, UITableViewDataSource =======================
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// return _expressAdViews.count*2;
// return 2;
return _dataArrM.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([_dataArrM[indexPath.row] isKindOfClass:[BYExamCellModelElement class]]) {
return ((BYExamCellModelElement *)_dataArrM[indexPath.row]).cellh;
} else {
CGFloat height = ([_dataArrM[indexPath.row] expressView]).frame.size.height;
return height;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
if ([_dataArrM[indexPath.row] isKindOfClass:[BYExamCellModelElement class]]) {
cell = [tableView dequeueReusableCellWithIdentifier:@"ExamTableViewCell"];
((ExamTableViewCell *)cell).item = _dataArrM[indexPath.row];
return cell;
} else {
cell = [self.tableView dequeueReusableCellWithIdentifier:@"nativeexpresscell" forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIView *subView = (UIView *)[cell.contentView viewWithTag:1000];
if ([subView superview]) {
[subView removeFromSuperview];
}
UIView *view = [_dataArrM[indexPath.row] expressView];
view.tag = 1000;
[cell.contentView addSubview:view];
cell.accessibilityIdentifier = @"nativeTemp_ad";
[view mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(@0);
}];
return cell;
}
}
@end