ATBannerAdWrapper.m 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. //
  2. // ATBannerAdWrapper.m
  3. // UnityContainer
  4. //
  5. // Created by Martin Lau on 2019/1/8.
  6. // Copyright © 2019 Martin Lau. All rights reserved.
  7. //
  8. #import "ATBannerAdWrapper.h"
  9. #import <AnyThinkBanner/AnyThinkBanner.h>
  10. #import "ATUnityUtilities.h"
  11. //5.6.6版本以上支持 admob 自适应banner (用到时再import该头文件)
  12. //#import <GoogleMobileAds/GoogleMobileAds.h>
  13. @interface ATBannerAdWrapper()<ATBannerDelegate>
  14. @property(nonatomic, readonly) NSMutableDictionary<NSString*, ATBannerView*> *bannerViewStorage;
  15. @property(nonatomic, readonly) BOOL interstitialOrRVBeingShown;
  16. @end
  17. static NSString *kATBannerSizeUsesPixelFlagKey = @"uses_pixel";
  18. static NSString *kATBannerAdLoadingExtraInlineAdaptiveWidthKey = @"inline_adaptive_width";
  19. static NSString *kATBannerAdLoadingExtraInlineAdaptiveOrientationKey = @"inline_adaptive_orientation";
  20. @implementation ATBannerAdWrapper
  21. +(instancetype)sharedInstance {
  22. static ATBannerAdWrapper *sharedInstance = nil;
  23. static dispatch_once_t onceToken;
  24. dispatch_once(&onceToken, ^{
  25. sharedInstance = [[ATBannerAdWrapper alloc] init];
  26. });
  27. return sharedInstance;
  28. }
  29. -(instancetype) init {
  30. self = [super init];
  31. if (self != nil) {
  32. _bannerViewStorage = [NSMutableDictionary<NSString*, ATBannerView*> dictionary];
  33. }
  34. return self;
  35. }
  36. -(NSString*) scriptWrapperClass {
  37. return @"ATBannerAdWrapper";
  38. }
  39. - (id)selWrapperClassWithDict:(NSDictionary *)dict callback:(void(*)(const char*, const char*))callback {
  40. NSString *selector = dict[@"selector"];
  41. NSArray<NSString*>* arguments = dict[@"arguments"];
  42. NSString *firstObject = @"";
  43. NSString *secondObject = @"";
  44. NSString *lastObject = @"";
  45. if (![ATUnityUtilities isEmpty:arguments]) {
  46. for (int i = 0; i < arguments.count; i++) {
  47. if (i == 0) { firstObject = arguments[i]; }
  48. else if (i == 1) { secondObject = arguments[i]; }
  49. else { lastObject = arguments[i]; }
  50. }
  51. }
  52. if ([selector isEqualToString:@"loadBannerAdWithPlacementID:customDataJSONString:callback:"]) {
  53. [self loadBannerAdWithPlacementID:firstObject customDataJSONString:secondObject callback:callback];
  54. } else if ([selector isEqualToString:@"showBannerAdWithPlacementID:rect:extraJsonString:"]) {
  55. [self showBannerAdWithPlacementID:firstObject rect:secondObject extraJsonString:lastObject];
  56. } else if ([selector isEqualToString:@"removeBannerAdWithPlacementID:"]) {
  57. [self removeBannerAdWithPlacementID:firstObject];
  58. } else if ([selector isEqualToString:@"showBannerAdWithPlacementID:"]) {
  59. [self showBannerAdWithPlacementID:firstObject];
  60. } else if ([selector isEqualToString:@"hideBannerAdWithPlacementID:"]) {
  61. [self hideBannerAdWithPlacementID:firstObject];
  62. } else if ([selector isEqualToString:@"checkAdStatus:"]) {
  63. return [self checkAdStatus:firstObject];
  64. } else if ([selector isEqualToString:@"clearCache"]) {
  65. [self clearCache];
  66. } else if ([selector isEqualToString:@"getValidAdCaches:"]) {
  67. return [self getValidAdCaches:firstObject];
  68. }
  69. return nil;
  70. }
  71. -(void) loadBannerAdWithPlacementID:(NSString*)placementID customDataJSONString:(NSString*)customDataJSONString callback:(void(*)(const char*, const char*))callback {
  72. [self setCallBack:callback forKey:placementID];
  73. NSMutableDictionary *extra = [NSMutableDictionary dictionary];
  74. if ([customDataJSONString isKindOfClass:[NSString class]] && [customDataJSONString length] > 0) {
  75. NSDictionary *extraDict = [NSJSONSerialization JSONObjectWithData:[customDataJSONString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil];
  76. NSLog(@"extraDict = %@", extraDict);
  77. CGFloat scale = [extraDict[kATBannerSizeUsesPixelFlagKey] boolValue] ? [UIScreen mainScreen].nativeScale : 1.0f;
  78. if ([extraDict[kATAdLoadingExtraBannerAdSizeKey] isKindOfClass:[NSString class]] && [[extraDict[kATAdLoadingExtraBannerAdSizeKey] componentsSeparatedByString:@"x"] count] == 2) {
  79. NSArray<NSString*>* com = [extraDict[kATAdLoadingExtraBannerAdSizeKey] componentsSeparatedByString:@"x"];
  80. extra[kATAdLoadingExtraBannerAdSizeKey] = [NSValue valueWithCGSize:CGSizeMake([com[0] doubleValue] / scale, [com[1] doubleValue] / scale)];
  81. }
  82. // // admob 自适应banner,5.6.6版本以上支持
  83. // if (extraDict[kATBannerAdLoadingExtraInlineAdaptiveWidthKey] != nil && extraDict[kATBannerAdLoadingExtraInlineAdaptiveOrientationKey] != nil) {
  84. // //GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth 自适应
  85. // //GADPortraitAnchoredAdaptiveBannerAdSizeWithWidth 竖屏
  86. // //GADLandscapeAnchoredAdaptiveBannerAdSizeWithWidth 横屏
  87. // CGFloat admobBannerWidth = [extraDict[kATBannerAdLoadingExtraInlineAdaptiveWidthKey] doubleValue];
  88. // GADAdSize admobSize;
  89. // if ([extraDict[kATBannerAdLoadingExtraInlineAdaptiveOrientationKey] integerValue] == 1) {
  90. // admobSize = GADPortraitAnchoredAdaptiveBannerAdSizeWithWidth(admobBannerWidth);
  91. // } else if ([extraDict[kATBannerAdLoadingExtraInlineAdaptiveOrientationKey] integerValue] == 2) {
  92. // admobSize = GADLandscapeAnchoredAdaptiveBannerAdSizeWithWidth(admobBannerWidth);
  93. // } else {
  94. // admobSize = GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(admobBannerWidth);
  95. // }
  96. //
  97. // extra[kATAdLoadingExtraAdmobBannerSizeKey] = [NSValue valueWithCGSize:admobSize.size];
  98. // extra[kATAdLoadingExtraAdmobAdSizeFlagsKey] = @(admobSize.flags);
  99. // }
  100. }
  101. if (extra[kATAdLoadingExtraBannerAdSizeKey] == nil) {
  102. extra[kATAdLoadingExtraBannerAdSizeKey] = [NSValue valueWithCGSize:CGSizeMake(320.0f, 50.0f)];
  103. }
  104. NSLog(@"extra = %@", extra);
  105. [[ATAdManager sharedManager] loadADWithPlacementID:placementID extra:extra delegate:self];
  106. }
  107. -(NSString*) checkAdStatus:(NSString *)placementID {
  108. ATCheckLoadModel *checkLoadModel = [[ATAdManager sharedManager] checkBannerLoadStatusForPlacementID:placementID];
  109. NSMutableDictionary *statusDict = [NSMutableDictionary dictionary];
  110. statusDict[@"isLoading"] = @(checkLoadModel.isLoading);
  111. statusDict[@"isReady"] = @(checkLoadModel.isReady);
  112. statusDict[@"adInfo"] = checkLoadModel.adOfferInfo;
  113. NSLog(@"ATBannerAdWrapper::statusDict = %@", statusDict);
  114. return statusDict.jsonFilterString;
  115. }
  116. -(NSString*) getValidAdCaches:(NSString *)placementID {
  117. NSArray *array = [[ATAdManager sharedManager] getBannerValidAdsForPlacementID:placementID];
  118. NSLog(@"ATNativeAdWrapper::array = %@", array);
  119. return array.jsonFilterString;
  120. }
  121. UIEdgeInsets SafeAreaInsets_ATUnityBanner() {
  122. return ([[UIApplication sharedApplication].keyWindow respondsToSelector:@selector(safeAreaInsets)] ? [UIApplication sharedApplication].keyWindow.safeAreaInsets : UIEdgeInsetsZero);
  123. }
  124. -(void) showBannerAdWithPlacementID:(NSString*)placementID rect:(NSString*)rect extraJsonString:(NSString*)extraJsonString {
  125. dispatch_async(dispatch_get_main_queue(), ^{
  126. if ([rect isKindOfClass:[NSString class]] && [rect dataUsingEncoding:NSUTF8StringEncoding] != nil) {
  127. NSDictionary *extraDict = ([extraJsonString isKindOfClass:[NSString class]] && [extraJsonString dataUsingEncoding:NSUTF8StringEncoding] != nil) ? [NSJSONSerialization JSONObjectWithData:[extraJsonString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil] : nil;
  128. NSDictionary *rectDict = [NSJSONSerialization JSONObjectWithData:[rect dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil];
  129. NSLog(@"rectDict = %@", rectDict);
  130. CGFloat scale = [rectDict[kATBannerSizeUsesPixelFlagKey] boolValue] ? [UIScreen mainScreen].nativeScale : 1.0f;
  131. ATBannerView *bannerView = [[ATAdManager sharedManager] retrieveBannerViewForPlacementID:placementID scene:extraDict[kATUnityUtilitiesAdShowingExtraScenarioKey]];
  132. bannerView.delegate = self;
  133. UIButton *bannerCointainer = [UIButton buttonWithType:UIButtonTypeCustom];
  134. [bannerCointainer addTarget:self action:@selector(noop) forControlEvents:UIControlEventTouchUpInside];
  135. NSString *position = rectDict[@"position"];
  136. CGSize totalSize = [UIApplication sharedApplication].keyWindow.rootViewController.view.bounds.size;
  137. UIEdgeInsets safeAreaInsets = SafeAreaInsets_ATUnityBanner();
  138. if ([@"top" isEqualToString:position]) {
  139. bannerCointainer.frame = CGRectMake((totalSize.width - CGRectGetWidth(bannerView.bounds)) / 2.0f, safeAreaInsets.top , CGRectGetWidth(bannerView.bounds), CGRectGetHeight(bannerView.bounds));
  140. } else if ([@"bottom" isEqualToString:position]) {
  141. bannerCointainer.frame = CGRectMake((totalSize.width - CGRectGetWidth(bannerView.bounds)) / 2.0f, totalSize.height - safeAreaInsets.bottom - CGRectGetHeight(bannerView.bounds) , CGRectGetWidth(bannerView.bounds), CGRectGetHeight(bannerView.bounds));
  142. } else {
  143. bannerCointainer.frame = CGRectMake([rectDict[@"x"] doubleValue] / scale, [rectDict[@"y"] doubleValue] / scale, [rectDict[@"width"] doubleValue] / scale, [rectDict[@"height"] doubleValue] / scale);
  144. }
  145. bannerView.frame = bannerCointainer.bounds;
  146. [bannerCointainer addSubview:bannerView];
  147. // bannerCointainer.layer.borderColor = [UIColor redColor].CGColor;
  148. // bannerCointainer.layer.borderWidth = .5f;
  149. [[UIApplication sharedApplication].keyWindow.rootViewController.view addSubview:bannerCointainer];
  150. self->_bannerViewStorage[placementID] = bannerCointainer;
  151. }
  152. });
  153. }
  154. -(void) noop {
  155. }
  156. -(void) removeBannerAdWithPlacementID:(NSString*)placementID {
  157. dispatch_async(dispatch_get_main_queue(), ^{
  158. [self->_bannerViewStorage[placementID] removeFromSuperview];
  159. [self->_bannerViewStorage removeObjectForKey:placementID];
  160. });
  161. }
  162. -(void) showBannerAdWithPlacementID:(NSString*)placementID {
  163. dispatch_async(dispatch_get_main_queue(), ^{
  164. ATBannerView *bannerView = self->_bannerViewStorage[placementID];
  165. if (bannerView.superview != nil && !_interstitialOrRVBeingShown) { bannerView.hidden = NO; }
  166. });
  167. }
  168. -(void) hideBannerAdWithPlacementID:(NSString*)placementID {
  169. dispatch_async(dispatch_get_main_queue(), ^{
  170. ATBannerView *bannerView = self->_bannerViewStorage[placementID];
  171. if (bannerView.superview != nil) { bannerView.hidden = YES; }
  172. });
  173. }
  174. -(void) clearCache {
  175. }
  176. #pragma mark - banner delegate method(s)
  177. -(void) didFinishLoadingADWithPlacementID:(NSString *)placementID {
  178. [self invokeCallback:@"OnBannerAdLoad" placementID:placementID error:nil extra:nil];
  179. }
  180. -(void) didFailToLoadADWithPlacementID:(NSString*)placementID error:(NSError*)error {
  181. error = error != nil ? error : [NSError errorWithDomain:@"com.anythink.Unity3DPackage" code:100001 userInfo:@{NSLocalizedDescriptionKey:@"AT has failed to load ad", NSLocalizedFailureReasonErrorKey:@"AT has failed to load ad"}];
  182. [self invokeCallback:@"OnBannerAdLoadFail" placementID:placementID error:error extra:nil];
  183. }
  184. // ad
  185. - (void)didStartLoadingADSourceWithPlacementID:(NSString *)placementID extra:(NSDictionary*)extra{
  186. [self invokeCallback:@"startLoadingADSource" placementID:placementID error:nil extra:extra];
  187. }
  188. - (void)didFinishLoadingADSourceWithPlacementID:(NSString *)placementID extra:(NSDictionary*)extra{
  189. [self invokeCallback:@"finishLoadingADSource" placementID:placementID error:nil extra:extra];
  190. }
  191. - (void)didFailToLoadADSourceWithPlacementID:(NSString*)placementID extra:(NSDictionary*)extra error:(NSError*)error{
  192. [self invokeCallback:@"failToLoadADSource" placementID:placementID error:error extra:extra];
  193. }
  194. // bidding
  195. - (void)didStartBiddingADSourceWithPlacementID:(NSString *)placementID extra:(NSDictionary*)extra{
  196. [self invokeCallback:@"startBiddingADSource" placementID:placementID error:nil extra:extra];
  197. }
  198. - (void)didFinishBiddingADSourceWithPlacementID:(NSString *)placementID extra:(NSDictionary*)extra{
  199. [self invokeCallback:@"finishBiddingADSource" placementID:placementID error:nil extra:extra];
  200. }
  201. - (void)didFailBiddingADSourceWithPlacementID:(NSString*)placementID extra:(NSDictionary*)extra error:(NSError*)error{
  202. [self invokeCallback:@"failBiddingADSource" placementID:placementID error:error extra:extra];
  203. }
  204. -(void) bannerView:(ATBannerView *)bannerView didShowAdWithPlacementID:(NSString *)placementID extra:(NSDictionary *)extra {
  205. [self invokeCallback:@"OnBannerAdImpress" placementID:placementID error:nil extra:extra];
  206. }
  207. -(void) bannerView:(ATBannerView*)bannerView didClickWithPlacementID:(NSString*)placementID extra:(NSDictionary *)extra {
  208. [self invokeCallback:@"OnBannerAdClick" placementID:placementID error:nil extra:extra];
  209. }
  210. -(void) bannerView:(ATBannerView *)bannerView didTapCloseButtonWithPlacementID:(NSString *)placementID extra:(NSDictionary *)extra {
  211. [self invokeCallback:@"OnBannerAdCloseButtonTapped" placementID:placementID error:nil extra:extra];
  212. }
  213. -(void) bannerView:(ATBannerView*)bannerView didCloseWithPlacementID:(NSString*)placementID extra:(NSDictionary *)extra {
  214. [self invokeCallback:@"OnBannerAdClose" placementID:placementID error:nil extra:extra];
  215. }
  216. -(void) bannerView:(ATBannerView *)bannerView didAutoRefreshWithPlacement:(NSString *)placementID extra:(NSDictionary *)extra {
  217. [self invokeCallback:@"OnBannerAdAutoRefresh" placementID:placementID error:nil extra:extra];
  218. }
  219. -(void) bannerView:(ATBannerView *)bannerView failedToAutoRefreshWithPlacementID:(NSString *)placementID error:(NSError *)error {
  220. error = error != nil ? error : [NSError errorWithDomain:@"com.anythink.Unity3DPackage" code:100001 userInfo:@{NSLocalizedDescriptionKey:@"AT has failed to refresh ad", NSLocalizedFailureReasonErrorKey:@"AT has failed to refresh ad"}];
  221. [self invokeCallback:@"OnBannerAdAutoRefreshFail" placementID:placementID error:error extra:nil];
  222. }
  223. @end