FqBUDExpressNativeAd.m 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. //
  2. // FqBUDExpressNativeAd.m
  3. // XenonSDK
  4. //
  5. // Created by fq on 2021/4/23.
  6. // Copyright © 2021 SAGESSE. All rights reserved.
  7. //
  8. #import "FqBUDExpressNativeAd.h"
  9. #import "GMTools.h"
  10. #import "XSNetwork.h"
  11. @interface FqBUDExpressNativeAd()<BUNativeExpressAdViewDelegate>
  12. @property (strong, nonatomic) NSMutableArray<__kindof BUNativeExpressAdView *> *expressAdViews;
  13. @property (strong, nonatomic) BUNativeExpressAdManager *nativeExpressAdManager;
  14. @property (strong, nonatomic) NSTimer *timer;
  15. @property(nonatomic,assign)CGRect rect1;
  16. @property(nonatomic,assign)NSInteger viewSize;
  17. @property(nonatomic,assign)BOOL isResourceReadly;
  18. @property(nonatomic,strong)void(^nativeCallback)(BOOL);
  19. @end
  20. @implementation FqBUDExpressNativeAd
  21. -(instancetype)init{
  22. if (self = [super init]) {
  23. self.agentName = @"ChuanSANJIA"; //平台名称
  24. self.adUnitId = @"native";
  25. self.type = @"native"; //广告类型
  26. NSDictionary *infos = [[NSBundle mainBundle] infoDictionary];
  27. self.adUnitId = [infos objectForKey:@"csj-native-unitId"]; //广告组ID
  28. self.isResourceReadly = NO;
  29. //[self loadNativeAdWithSlotID:self.adUnitId];
  30. }
  31. return self;
  32. }
  33. -(BOOL)isAdReady {
  34. return self.isResourceReadly;
  35. }
  36. //打开广告
  37. -(void)openNativeAd:(NSString *)adName WidthCGRect:(CGRect)rect BUSize:(NSInteger)size callback:(void (^)(BOOL))callback {
  38. self.adId = adName;
  39. self.nativeCallback = callback;
  40. self.rect1 = rect;
  41. self.viewSize = size;
  42. //加载广告
  43. [self loadNativeAdWithSlotID:self.adUnitId CGRect:rect BUSize:size];
  44. // dispatch_async(dispatch_get_main_queue(), ^{
  45. // NSInteger count = 2;
  46. // [self.nativeExpressAdManager loadAdDataWithCount:count];
  47. // });
  48. }
  49. //加载广告
  50. - (void)loadNativeAdWithSlotID:(NSString *)slotId CGRect:(CGRect)rect BUSize:(NSInteger)size{
  51. if (slotId.length == 0) {
  52. NSLog(@"【穿山甲广告】,error=原生广告广告位id为空!!!");
  53. return;
  54. }
  55. if (!self.expressAdViews) {
  56. self.expressAdViews = [NSMutableArray arrayWithCapacity:20];
  57. }
  58. BUAdSlot *slot1 = [[BUAdSlot alloc] init];
  59. slot1.ID = slotId;
  60. slot1.AdType = BUAdSlotAdTypeFeed;
  61. slot1.supportRenderControl = YES;
  62. //BUProposalSize_Interstitial600_400 这里需要跟穿山甲后台设置保持一致.
  63. BUSize *imgSize = [BUSize sizeBy:size];
  64. slot1.imgSize = imgSize;
  65. slot1.position = BUAdSlotPositionFeed;
  66. // self.nativeExpressAdManager可以重用
  67. if (!self.nativeExpressAdManager) {
  68. //CGSizeMake(600, 400)
  69. self.nativeExpressAdManager = [[BUNativeExpressAdManager alloc] initWithSlot:slot1 adSize:CGSizeMake(rect.size.width, rect.size.height)];
  70. }
  71. // 不支持中途更改代理,中途更改代理会导致接收不到广告相关回调,如若存在中途更改代理场景,需自行处理相关逻辑,确保广告相关回调正常执行。
  72. self.nativeExpressAdManager.delegate = self;
  73. NSInteger count = 2;
  74. [self.nativeExpressAdManager loadAdDataWithCount:count];
  75. //上报数据
  76. [XSNetwork adRecord:@"quest" spaceId:self.adId agentName:self.agentName medium:self.medium adUnitId:self.adUnitId type:self.type unitAdId:self.unitAdId errorMsg:self.errorMsg];
  77. }
  78. #pragma mark - BUNativeExpressAdViewDelegate
  79. - (void)nativeExpressAdSuccessToLoad:(BUNativeExpressAdManager *)nativeExpressAd views:(NSArray<__kindof BUNativeExpressAdView *> *)views {
  80. [self.expressAdViews removeAllObjects];//【重要】不能保存太多view,需要在合适的时机手动释放不用的,否则内存会过大
  81. if (views.count) {
  82. [self.expressAdViews addObjectsFromArray:views];
  83. UIWindow *keyWindow = [GMTools getKeyWindow];
  84. [views enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  85. BUNativeExpressAdView *expressView = (BUNativeExpressAdView *)obj;
  86. expressView.rootViewController = keyWindow.rootViewController;
  87. // important: 此处会进行WKWebview的渲染,建议一次最多预加载三个广告,如果超过3个会很大概率导致WKWebview渲染失败。
  88. [expressView render];
  89. // *stop = YES;
  90. }];
  91. }
  92. UIViewController *v1 = [GMTools getViewControl];
  93. BUNativeExpressAdView *childView = (BUNativeExpressAdView *)[self.expressAdViews firstObject];
  94. //childView.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2, [UIScreen mainScreen].bounds.size.height/2);
  95. childView.center = CGPointMake(self.rect1.origin.x, self.rect1.origin.y);
  96. [v1.view addSubview:childView];
  97. [self pbud_logWithSEL:_cmd msg:@""];
  98. }
  99. - (void)nativeExpressAdFailToLoad:(BUNativeExpressAdManager *)nativeExpressAd error:(NSError *)error {
  100. [self pbud_logWithSEL:_cmd msg:[NSString stringWithFormat:@"error:%@", error]];
  101. self.errorMsg = [NSString stringWithFormat:@"code=%ld,domain=%@,describe=%@",(long)error.code,error.domain,error.userInfo];
  102. //广告加载失败回调
  103. self.isResourceReadly = NO;
  104. }
  105. - (void)nativeExpressAdViewRenderSuccess:(BUNativeExpressAdView *)nativeExpressAdView {
  106. UIViewController *v1 = [GMTools getViewControl];
  107. BUNativeExpressAdView *childView = (BUNativeExpressAdView *)[self.expressAdViews firstObject];
  108. childView.center = CGPointMake(self.rect1.origin.x, self.rect1.origin.y);
  109. [v1.view addSubview:childView];
  110. //回调成功
  111. self.isResourceReadly = YES;
  112. if (self.nativeCallback) {
  113. self.nativeCallback(self.isResourceReadly);
  114. }
  115. static dispatch_once_t onceToken;
  116. dispatch_once(&onceToken, ^{
  117. self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateCurrentPlayedTime) userInfo:nil repeats:YES];
  118. [self.timer fire];
  119. });
  120. [self pbud_logWithSEL:_cmd msg:[NSString stringWithFormat:@"nativeExpressAdView.videoDuration:%ld", (long)nativeExpressAdView.videoDuration]];
  121. }
  122. - (void)updateCurrentPlayedTime {
  123. for (BUNativeExpressAdView *nativeExpressAdView in self.expressAdViews) {
  124. [self pbud_logWithSEL:_cmd msg:[NSString stringWithFormat:@"nativeExpressAdView.currentPlayedTime:%.4f", nativeExpressAdView.currentPlayedTime]];
  125. }
  126. }
  127. - (void)nativeExpressAdView:(BUNativeExpressAdView *)nativeExpressAdView stateDidChanged:(BUPlayerPlayState)playerState {
  128. [self pbud_logWithSEL:_cmd msg:[NSString stringWithFormat:@"playerState:%ld", (long)playerState]];
  129. }
  130. - (void)nativeExpressAdViewRenderFail:(BUNativeExpressAdView *)nativeExpressAdView error:(NSError *)error {
  131. [self pbud_logWithSEL:_cmd msg:[NSString stringWithFormat:@"error:%@ 此广告将会从列表中移除", error]];
  132. [self.expressAdViews removeObject:nativeExpressAdView];
  133. UIViewController *v1 = [GMTools getViewControl];
  134. if (self.expressAdViews.count > 0) {
  135. [v1.view addSubview:[self.expressAdViews firstObject]];
  136. }
  137. self.errorMsg = [NSString stringWithFormat:@"code=%ld,domain=%@,describe=%@",(long)error.code,error.domain,error.userInfo];
  138. //回调失败
  139. self.isResourceReadly = NO;
  140. if (self.nativeCallback) {
  141. self.nativeCallback(self.isResourceReadly);
  142. }
  143. }
  144. - (void)nativeExpressAdViewWillShow:(BUNativeExpressAdView *)nativeExpressAdView {
  145. [self pbud_logWithSEL:_cmd msg:@""];
  146. //上报数据
  147. [XSNetwork adRecord:@"show" spaceId:self.adId agentName:self.agentName medium:self.medium adUnitId:self.adUnitId type:self.type unitAdId:self.unitAdId errorMsg:self.errorMsg];
  148. }
  149. - (void)nativeExpressAdViewDidClick:(BUNativeExpressAdView *)nativeExpressAdView {
  150. [self pbud_logWithSEL:_cmd msg:@""];
  151. //上报数据
  152. [XSNetwork adRecord:@"click" spaceId:self.adId agentName:self.agentName medium:self.medium adUnitId:self.adUnitId type:self.type unitAdId:self.unitAdId errorMsg:self.errorMsg];
  153. }
  154. - (void)nativeExpressAdViewPlayerDidPlayFinish:(BUNativeExpressAdView *)nativeExpressAdView error:(NSError *)error {
  155. [self pbud_logWithSEL:_cmd msg:@""];
  156. }
  157. - (void)nativeExpressAdView:(BUNativeExpressAdView *)nativeExpressAdView dislikeWithReason:(NSArray<BUDislikeWords *> *)filterWords {//【重要】需要在点击叉以后 在这个回调中移除视图,否则,会出现用户点击叉无效的情况
  158. [self.expressAdViews removeObject:nativeExpressAdView];
  159. [nativeExpressAdView removeFromSuperview];
  160. [self pbud_logWithSEL:_cmd msg:@""];
  161. self.nativeExpressAdManager = nil;
  162. }
  163. - (void)nativeExpressAdViewDidClosed:(BUNativeExpressAdView *)nativeExpressAdView {
  164. [self pbud_logWithSEL:_cmd msg:@""];
  165. self.nativeExpressAdManager = nil;
  166. //上报数据
  167. [XSNetwork adRecord:@"close" spaceId:self.adId agentName:self.agentName medium:self.medium adUnitId:self.adUnitId type:self.type unitAdId:self.unitAdId errorMsg:self.errorMsg];
  168. }
  169. - (void)nativeExpressAdViewWillPresentScreen:(BUNativeExpressAdView *)nativeExpressAdView {
  170. [self pbud_logWithSEL:_cmd msg:@""];
  171. }
  172. - (void)nativeExpressAdViewDidCloseOtherController:(BUNativeExpressAdView *)nativeExpressAdView interactionType:(BUInteractionType)interactionType {
  173. NSString *str;
  174. if (interactionType == BUInteractionTypePage) {
  175. str = @"ladingpage";
  176. } else if (interactionType == BUInteractionTypeVideoAdDetail) {
  177. str = @"videoDetail";
  178. } else {
  179. str = @"appstoreInApp";
  180. }
  181. [self pbud_logWithSEL:_cmd msg:str];
  182. }
  183. - (void)pbud_logWithSEL:(SEL)sel msg:(NSString *)msg {
  184. NSLog(@"SDKDemoDelegate BUNativeExpressFeedAdView In VC (%@) extraMsg:%@", NSStringFromSelector(sel), msg);
  185. }
  186. @end