cordova-plugin-admob-nextgen 2.0.3-beta.1 → 2.1.4-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,7 +21,8 @@ It moves away from legacy implementations to modern `SurfaceControl`, optimized
21
21
  > (NEW) ⚡️ Next-Gen special capacitor: [capacitor-admob-nextgen](https://github.com/swaplab-engine/capacitor-admob-nextgen)
22
22
  ---
23
23
 
24
- ## 🚀 Why Next-Gen?
24
+ <details>
25
+ <summary>Click to view: 🚀 Why Next-Gen?</summary>
25
26
 
26
27
  Google has introduced a fundamental shift in how ads are rendered on Android.
27
28
 
@@ -97,9 +98,10 @@ This plugin prioritizes the safety of your AdMob account and the stability of yo
97
98
 
98
99
  * **Background Thread Loading**: All ad requests are dispatched on background threads, ensuring your app's UI never freezes.
99
100
 
100
-
101
101
  ---
102
102
 
103
+ </details>
104
+
103
105
 
104
106
  ## Cordova/Capacitor/Framework7 AdMob Next-Gen:
105
107
 
@@ -115,9 +117,9 @@ This plugin is regularly updated to support the latest standards.
115
117
 
116
118
  | Component | Platform | Version | Release Notes |
117
119
  | :--- | :--- | :--- | :--- |
118
- | **GMA Next-Gen SDK** | Android | **1.4.0** | [View Notes](https://developers.google.com/admob/android/next-gen/rel-notes) |
120
+ | **GMA Next-Gen SDK** | Android | **1.5.0** | [View Notes](https://developers.google.com/admob/android/next-gen/rel-notes) |
119
121
  | **UMP SDK** | Android | **4.0.0** | [View Notes](https://developers.google.com/admob/android/privacy/release-notes) |
120
- | **Mobile Ads SDK** | iOS | **13.3.0** | [View Notes](https://developers.google.com/admob/ios/rel-notes) |
122
+ | **Mobile Ads SDK** | iOS | **13.11.0** | [View Notes](https://developers.google.com/admob/ios/rel-notes) |
121
123
  | **UMP SDK** | iOS | **3.1.0** | [View Notes](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/privacy/download) |
122
124
 
123
125
  ### 🎉 View all plugin release notes
@@ -143,6 +145,9 @@ Add this to your `config.xml` to restore the plugin automatically.
143
145
 
144
146
  ---
145
147
 
148
+ ### 📱 iOS 27 & iPhone Duo Support
149
+ - 👉 [**Releases notes**](https://github.com/swaplab-engine/cordova-plugin-admob-nextgen/releases/tag/2.1.4-beta)
150
+
146
151
  ## (Optional)
147
152
 
148
153
  ### Supporting Mediation: **[⚡ admob-mediation-suite ](https://github.com/swaplab-engine/admob-mediation-suite)** (Optional)
@@ -638,30 +643,8 @@ document.addEventListener('on.rewarded.loaded', (e) => {
638
643
 
639
644
  ---
640
645
 
641
-
642
646
  ## ⚖️ Revenue Policy
643
647
 
644
- **No Ad-Sharing. No Hidden Fees.**
645
-
646
- Unlike many other free plugins, this project is clean:
647
648
  * **0% Revenue Share:** This plugin do not inject our own Ad Unit IDs into your traffic.
648
649
  * **100% Control:** Every impression and click goes directly to your AdMob account.
649
- * **Transparent Source:** The code is open source. You can verify that no third-party SDKs or hidden backdoors exist.
650
-
651
- ---
652
-
653
- ## ❤️ Support the Project
654
-
655
- This plugin is developed and maintained in my free time.
656
- If it saved you hours of work, consider supporting the development!
657
-
658
- <a href="https://www.buymeacoffee.com/emi.indo" target="_blank">
659
- <img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" >
660
- </a>
661
-
662
- Your support helps me keep the dependencies updated and the cleaner script running smoothly.
663
-
664
-
665
- <p align="center">
666
- Built with ❤️ by <b>Swaplab Engine</b> (formerly EMI-INDO).
667
- </p>
650
+ * **Transparent Source:** The code is open source.
@@ -158,7 +158,7 @@ function run() {
158
158
  admob = {
159
159
  APP_ID_ANDROID: appIdAndroid ? appIdAndroid[1] : "ca-app-pub-3940256099942544~3347511713",
160
160
  APP_ID_IOS: appIdIos ? appIdIos[1] : "ca-app-pub-3940256099942544~1458002511",
161
- NEXT_GEN_SDK_VERSION: sdk ? sdk[1] : "1.4.0",
161
+ NEXT_GEN_SDK_VERSION: sdk ? sdk[1] : "1.5.0",
162
162
  UMP_VERSION: ump ? ump[1] : "4.0.0"
163
163
  };
164
164
  }
@@ -167,7 +167,7 @@ function run() {
167
167
  injectExclusionRules();
168
168
  if (admob?.NEXT_GEN_SDK_VERSION || admob?.UMP_VERSION) {
169
169
  updateGradleDependencies(
170
- admob.NEXT_GEN_SDK_VERSION || "1.4.0",
170
+ admob.NEXT_GEN_SDK_VERSION || "1.5.0",
171
171
  admob.UMP_VERSION || "4.0.0"
172
172
  );
173
173
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cordova-plugin-admob-nextgen",
3
- "version": "2.0.3-beta.1",
3
+ "version": "2.1.4-beta",
4
4
  "description": "Google Mobile Ads Next Gen SDK for Cordova. High performance and modular architecture. ",
5
5
  "cordova": {
6
6
  "id": "cordova-plugin-admob-nextgen",
package/plugin.xml CHANGED
@@ -1,6 +1,6 @@
1
1
  <?xml version='1.0' encoding='utf-8'?>
2
2
  <plugin id="cordova-plugin-admob-nextgen"
3
- version="2.0.3-beta.1"
3
+ version="2.0.3"
4
4
  xmlns="http://apache.org/cordova/ns/plugins/1.0"
5
5
  xmlns:android="http://schemas.android.com/apk/res/android">
6
6
 
@@ -54,7 +54,7 @@
54
54
 
55
55
  </platform>
56
56
 
57
- <preference name="NEXT_GEN_SDK_VERSION" default="1.4.0" />
57
+ <preference name="NEXT_GEN_SDK_VERSION" default="1.5.0" />
58
58
  <preference name="UMP_VERSION" default="4.0.0" />
59
59
  <!-- Sample AdMob app ID: ca-app-pub-3940256099942544~3347511713 -->
60
60
  <preference name="APP_ID_ANDROID" default="ca-app-pub-3940256099942544~3347511713" />
@@ -139,7 +139,7 @@
139
139
  </config>
140
140
  <pods use-frameworks="true">
141
141
  <pod name="GoogleUserMessagingPlatform" spec="~> 3.1.0" />
142
- <pod name="Google-Mobile-Ads-SDK" spec="~> 13.1.0" />
142
+ <pod name="Google-Mobile-Ads-SDK" spec="~> 13.11.0" />
143
143
  </pods>
144
144
  </podspec>
145
145
 
@@ -148,7 +148,7 @@ public class ConsentExecutor {
148
148
  String purposeConsents = prefs.getString("IABTCF_PurposeConsents", "");
149
149
  String purposeLegitimateInterests = prefs.getString("IABTCF_PurposeLegitimateInterests", "");
150
150
  String vendorConsents = prefs.getString("IABTCF_VendorConsents", "");
151
- int gdprApplies = prefs.getInt("IABTCF_gdprApplies", 0);
151
+ int gdprApplies = prefs.getInt("IABTCF_gdprApplies", -1);
152
152
 
153
153
  tcData.put("purposeConsents", purposeConsents);
154
154
  tcData.put("purposeLegitimateInterests", purposeLegitimateInterests);
@@ -162,7 +162,15 @@ public class ConsentExecutor {
162
162
  boolean isAdMobNonPersonalizedAdsAllowed = false;
163
163
  String adMobConsentStatus = "Unknown";
164
164
 
165
- if (gdprApplies == 0) {
165
+ if (gdprApplies == -1) {
166
+
167
+ statusMessage = "TCF data missing. Consent not yet gathered.";
168
+ adMobConsentStatus = "UNKNOWN";
169
+
170
+ isPersonalizedAllowed = false;
171
+ isAdMobPersonalizedAdsAllowed = false;
172
+ isAdMobNonPersonalizedAdsAllowed = false;
173
+ } else if (gdprApplies == 0) {
166
174
 
167
175
  isPersonalizedAllowed = true;
168
176
  statusMessage = "Not GDPR region. Personalized Ads allowed by default.";
@@ -54,14 +54,16 @@
54
54
  }
55
55
  }
56
56
 
57
- if (options[@"tagForChildDirectedTreatment"]) {
58
- BOOL isChildDirected = [options[@"tagForChildDirectedTreatment"] boolValue];
59
- requestConfig.tagForChildDirectedTreatment = @(isChildDirected);
60
- }
61
-
62
- if (options[@"tagForUnderAgeOfConsent"]) {
63
- BOOL isUnderAge = [options[@"tagForUnderAgeOfConsent"] boolValue];
64
- requestConfig.tagForUnderAgeOfConsent = @(isUnderAge);
57
+ NSNumber *childDirected = options[@"tagForChildDirectedTreatment"];
58
+ NSNumber *underAge = options[@"tagForUnderAgeOfConsent"];
59
+
60
+ if (childDirected != nil && [childDirected boolValue]) {
61
+ requestConfig.ageRestrictedTreatment = GADAgeRestrictedTreatmentChild;
62
+ } else if (underAge != nil && [underAge boolValue]) {
63
+ requestConfig.ageRestrictedTreatment = GADAgeRestrictedTreatmentTeen;
64
+ } else if ((childDirected != nil && ![childDirected boolValue]) ||
65
+ (underAge != nil && ![underAge boolValue])) {
66
+ requestConfig.ageRestrictedTreatment = GADAgeRestrictedTreatmentUnspecified;
65
67
  }
66
68
  }
67
69
 
@@ -79,6 +79,11 @@
79
79
  CDVPluginResult* res = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"Ad Ready"];
80
80
  [self.plugin.commandDelegate sendPluginResult:res callbackId:command.callbackId];
81
81
  }
82
+
83
+ if (self.isAutoShow) {
84
+ [self showAdIfAvailable];
85
+ }
86
+
82
87
  }
83
88
  return;
84
89
  }
@@ -154,6 +159,12 @@
154
159
  return;
155
160
  }
156
161
 
162
+ if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
163
+ NSString *jsonStr = @"{\"code\":\"APP_IN_BACKGROUND\", \"message\":\"Ad presentation blocked: Application is currently in the background or inactive.\"}";
164
+ [self.plugin fireEvent:@"document" event:@"on.appopen.failed.show" withData:jsonStr];
165
+ return;
166
+ }
167
+
157
168
  self.isShowingAd = YES;
158
169
  [self.appOpenAd presentFromRootViewController:self.plugin.viewController];
159
170
  }
@@ -1,12 +1,28 @@
1
1
  #import "BannerExecutor.h"
2
2
  #import "AdMobNextGen.h"
3
3
 
4
+ @interface BoundsObserverView : UIView
5
+ @property (nonatomic, copy) void (^onBoundsChanged)(CGRect bounds);
6
+ @end
7
+
8
+ @implementation BoundsObserverView
9
+ - (void)layoutSubviews {
10
+ [super layoutSubviews];
11
+ if (self.onBoundsChanged) {
12
+ self.onBoundsChanged(self.bounds);
13
+ }
14
+ }
15
+ @end
16
+
4
17
  @interface BannerExecutor ()
5
18
 
6
19
  @property(nonatomic, weak) AdMobNextGen *plugin;
7
20
  @property(nonatomic, strong) GADBannerView *bannerView;
8
21
  @property(nonatomic, strong) GADBannerView *pendingBannerView;
9
22
 
23
+ @property(nonatomic, strong) BoundsObserverView *boundsObserverView;
24
+ @property(nonatomic, assign) CGFloat lastObservedWidth;
25
+
10
26
  @property(nonatomic, strong) NSString *lastAdUnitId;
11
27
  @property(nonatomic, strong) NSString *lastSizeStr;
12
28
  @property(nonatomic, strong) NSString *currentPosition;
@@ -48,17 +64,15 @@
48
64
  self.lastLoadTime = 0;
49
65
  self.minLoadInterval = 5.0;
50
66
 
51
- [[NSNotificationCenter defaultCenter]
52
- addObserver:self
53
- selector:@selector(layoutViews)
54
- name:UIDeviceOrientationDidChangeNotification
55
- object:nil];
56
67
  }
57
68
  return self;
58
69
  }
59
70
 
60
71
  - (void)dealloc {
61
- [[NSNotificationCenter defaultCenter] removeObserver:self];
72
+ dispatch_async(dispatch_get_main_queue(), ^{
73
+ [self.boundsObserverView removeFromSuperview];
74
+ self.boundsObserverView = nil;
75
+ });
62
76
  }
63
77
 
64
78
  #pragma mark - Smart Window Helper
@@ -90,6 +104,49 @@
90
104
  return window;
91
105
  }
92
106
 
107
+ - (void)startObservingBounds {
108
+ if (self.boundsObserverView != nil) return;
109
+
110
+ UIViewController *rootVC = self.plugin.viewController;
111
+ if (!rootVC) return;
112
+
113
+ self.lastObservedWidth = rootVC.view.bounds.size.width;
114
+
115
+ BoundsObserverView *observerView = [[BoundsObserverView alloc] init];
116
+ observerView.userInteractionEnabled = NO;
117
+ observerView.backgroundColor = [UIColor clearColor];
118
+ observerView.translatesAutoresizingMaskIntoConstraints = NO;
119
+
120
+ [rootVC.view addSubview:observerView];
121
+ [rootVC.view sendSubviewToBack:observerView];
122
+
123
+ [NSLayoutConstraint activateConstraints:@[
124
+ [observerView.leadingAnchor constraintEqualToAnchor:rootVC.view.leadingAnchor],
125
+ [observerView.trailingAnchor constraintEqualToAnchor:rootVC.view.trailingAnchor],
126
+ [observerView.topAnchor constraintEqualToAnchor:rootVC.view.topAnchor],
127
+ [observerView.bottomAnchor constraintEqualToAnchor:rootVC.view.bottomAnchor]
128
+ ]];
129
+
130
+ __weak typeof(self) weakSelf = self;
131
+ observerView.onBoundsChanged = ^(CGRect bounds) {
132
+ dispatch_async(dispatch_get_main_queue(), ^{
133
+ [weakSelf layoutViews];
134
+
135
+ CGFloat currentWidth = bounds.size.width;
136
+ if (fabs(weakSelf.lastObservedWidth - currentWidth) > 1.0) {
137
+ weakSelf.lastObservedWidth = currentWidth;
138
+
139
+ if (weakSelf.lastAdUnitId.length > 0) {
140
+ NSString *jsonStr = @"{\"orientation\":\"RESIZE\"}";
141
+ [weakSelf.plugin fireEvent:@"document" event:@"on.banner.orientation.changed" withData:jsonStr];
142
+ }
143
+ }
144
+ });
145
+ };
146
+
147
+ self.boundsObserverView = observerView;
148
+ }
149
+
93
150
  #pragma mark - Main Methods
94
151
 
95
152
  - (void)createBanner:(NSDictionary *)options
@@ -120,6 +177,9 @@
120
177
  }
121
178
 
122
179
  dispatch_async(dispatch_get_main_queue(), ^{
180
+
181
+ [self startObservingBounds];
182
+
123
183
  NSTimeInterval currentTime = [[NSDate date] timeIntervalSince1970];
124
184
 
125
185
  if (self.isLoading) {
@@ -247,79 +307,85 @@
247
307
  if ([sizeStr isEqualToString:@"LEADERBOARD"])
248
308
  return GADAdSizeLeaderboard;
249
309
 
250
- UIViewController *rootViewController = self.plugin.viewController;
251
- CGRect frame = rootViewController.view.frame;
252
- if (@available(iOS 11.0, *)) {
253
- frame = UIEdgeInsetsInsetRect(rootViewController.view.frame,
254
- rootViewController.view.safeAreaInsets);
255
- }
256
- return GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(
257
- frame.size.width);
310
+ UIWindow *window = [self getKeyWindow];
311
+ CGFloat screenW = window ? window.bounds.size.width : UIScreen.mainScreen.bounds.size.width;
312
+
313
+ if (window) {
314
+ screenW -= (window.safeAreaInsets.left + window.safeAreaInsets.right);
315
+ }
316
+
317
+ if ([sizeStr isEqualToString:@"LARGE_ANCHORED_ADAPTIVE"]) {
318
+ return GADLargeAnchoredAdaptiveBannerAdSizeWithWidth(screenW);
319
+ }
320
+
321
+ #pragma clang diagnostic push
322
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
323
+ return GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(screenW);
324
+ #pragma clang diagnostic pop
258
325
  }
259
326
 
260
327
  - (void)layoutViews {
261
328
  dispatch_async(dispatch_get_main_queue(), ^{
262
- UIViewController *rootVC = self.plugin.viewController;
263
- UIView *webView = self.plugin.webView;
264
- if (!rootVC || !webView)
265
- return;
329
+ UIViewController *rootVC = self.plugin.viewController;
330
+ UIView *webView = self.plugin.webView;
331
+ if (!rootVC || !webView) return;
266
332
 
267
- UIWindow *window = [self getKeyWindow];
268
- UIEdgeInsets safeArea =
269
- (window) ? window.safeAreaInsets : UIEdgeInsetsZero;
333
+ UIWindow *window = [self getKeyWindow];
334
+ if (!window) return;
270
335
 
271
- CGFloat screenH = UIScreen.mainScreen.bounds.size.height;
272
- CGFloat screenW = UIScreen.mainScreen.bounds.size.width;
336
+ UIEdgeInsets safeArea = window.safeAreaInsets;
273
337
 
274
- if (safeArea.bottom == 0 && screenH >= 812.0)
275
- safeArea.bottom = 34.0;
276
- if (safeArea.top == 0 && screenH >= 812.0)
277
- safeArea.top = 44.0;
338
+ CGFloat screenH = window.bounds.size.height;
339
+ CGFloat screenW = window.bounds.size.width;
278
340
 
279
- CGRect fullScreenRect = CGRectMake(0, 0, screenW, screenH);
341
+ if (safeArea.bottom == 0 && screenH >= 812.0) safeArea.bottom = 34.0;
342
+ if (safeArea.top == 0 && screenH >= 812.0) safeArea.top = 44.0;
280
343
 
281
- if (self.isBannerVisible && self.bannerView &&
282
- self.activeBannerHeight > 0) {
344
+ CGRect fullScreenRect = CGRectMake(0, 0, screenW, screenH);
283
345
 
284
- CGSize adSize = self.bannerView.intrinsicContentSize;
285
- CGFloat bH =
286
- adSize.height > 0 ? adSize.height : self.activeBannerHeight;
287
- CGFloat bW = adSize.width > 0 ? adSize.width
288
- : self.bannerView.bounds.size.width;
289
- CGFloat bX = (screenW - bW) / 2.0;
290
- CGFloat bY = 0;
346
+ if (self.isBannerVisible && self.bannerView && self.activeBannerHeight > 0) {
347
+ CGSize adSize = self.bannerView.intrinsicContentSize;
348
+ CGFloat bH = adSize.height > 0 ? adSize.height : self.activeBannerHeight;
349
+ CGFloat bW = adSize.width > 0 ? adSize.width : self.bannerView.bounds.size.width;
350
+ CGFloat bX = (screenW - bW) / 2.0;
351
+ CGFloat bY = 0;
291
352
 
292
- if ([self.currentPosition isEqualToString:@"top"]) {
293
- bY = safeArea.top;
294
- } else {
295
- bY = screenH - safeArea.bottom - bH;
296
- }
353
+ if ([self.currentPosition isEqualToString:@"top"]) {
354
+ bY = safeArea.top;
355
+ self.bannerView.frame = CGRectMake(bX, bY, bW, bH);
356
+ self.bannerView.hidden = NO;
297
357
 
298
- self.bannerView.frame = CGRectMake(bX, bY, bW, bH);
299
- self.bannerView.hidden = NO;
300
-
301
- if (!self.isOverlapping) {
302
- CGRect newWebFrame = fullScreenRect;
303
- if ([self.currentPosition isEqualToString:@"top"]) {
304
- newWebFrame.origin.y = bY + bH;
305
- newWebFrame.size.height = screenH - newWebFrame.origin.y;
306
- } else {
307
- newWebFrame.origin.y = 0;
308
- newWebFrame.size.height = bY;
309
- }
310
- webView.frame = newWebFrame;
311
- } else {
312
- webView.frame = fullScreenRect;
313
- }
314
- } else {
315
- if (self.bannerView)
316
- self.bannerView.hidden = YES;
317
- webView.frame = fullScreenRect;
318
- }
358
+ if (!self.isOverlapping) {
359
+ CGRect newWebFrame = fullScreenRect;
319
360
 
320
- if (self.bannerView && self.isBannerVisible) {
321
- [webView.superview bringSubviewToFront:self.bannerView];
322
- }
361
+ newWebFrame.origin.y = bY + bH;
362
+ newWebFrame.size.height = screenH - (bY + bH);
363
+ webView.frame = newWebFrame;
364
+ } else {
365
+ webView.frame = fullScreenRect;
366
+ }
367
+ } else {
368
+ bY = screenH - safeArea.bottom - bH;
369
+ self.bannerView.frame = CGRectMake(bX, bY, bW, bH);
370
+ self.bannerView.hidden = NO;
371
+
372
+ if (!self.isOverlapping) {
373
+ CGRect newWebFrame = fullScreenRect;
374
+ newWebFrame.origin.y = 0;
375
+ newWebFrame.size.height = bY;
376
+ webView.frame = newWebFrame;
377
+ } else {
378
+ webView.frame = fullScreenRect;
379
+ }
380
+ }
381
+ } else {
382
+ if (self.bannerView) self.bannerView.hidden = YES;
383
+ webView.frame = fullScreenRect;
384
+ }
385
+
386
+ if (self.bannerView && self.isBannerVisible) {
387
+ [webView.superview bringSubviewToFront:self.bannerView];
388
+ }
323
389
  });
324
390
  }
325
391
 
@@ -113,7 +113,9 @@
113
113
  NSString *purposeLegitimateInterests = [prefs stringForKey:@"IABTCF_PurposeLegitimateInterests"] ?: @"";
114
114
  NSString *vendorConsents = [prefs stringForKey:@"IABTCF_VendorConsents"] ?: @"";
115
115
  NSString *additionalConsent = [prefs stringForKey:@"IABTCF_AddtlConsent"] ?: @"";
116
- NSInteger gdprApplies = [prefs integerForKey:@"IABTCF_gdprApplies"];
116
+
117
+ id gdprAppliesObj = [prefs objectForKey:@"IABTCF_gdprApplies"];
118
+ NSInteger gdprApplies = gdprAppliesObj ? [gdprAppliesObj integerValue] : -1;
117
119
 
118
120
  tcData[@"purposeConsents"] = purposeConsents;
119
121
  tcData[@"purposeLegitimateInterests"] = purposeLegitimateInterests;
@@ -128,7 +130,15 @@
128
130
  BOOL isAdMobNonPersonalizedAdsAllowed = NO;
129
131
  NSString *adMobConsentStatus = @"Unknown";
130
132
 
131
- if (gdprApplies == 0) {
133
+ if (gdprAppliesObj == nil) {
134
+
135
+ statusMessage = @"TCF data missing. Consent not yet gathered.";
136
+ adMobConsentStatus = @"UNKNOWN";
137
+
138
+ isPersonalizedAllowed = NO;
139
+ isAdMobPersonalizedAdsAllowed = NO;
140
+ isAdMobNonPersonalizedAdsAllowed = NO;
141
+ } else if (gdprApplies == 0) {
132
142
  isPersonalizedAllowed = YES;
133
143
  statusMessage = @"Not GDPR region. Personalized Ads allowed by default.";
134
144
 
@@ -66,14 +66,17 @@
66
66
  GADRequestConfiguration *requestConfiguration = GADMobileAds.sharedInstance.requestConfiguration;
67
67
 
68
68
  NSNumber *coppaTag = [self parseBooleanFromDict:config key:@"tagForChildDirectedTreatment"];
69
- if (coppaTag != nil) {
70
- requestConfiguration.tagForChildDirectedTreatment = coppaTag;
69
+ NSNumber *tfuaTag = [self parseBooleanFromDict:config key:@"tagForUnderAgeOfConsent"];
71
70
 
72
- }
71
+ if (coppaTag != nil && [coppaTag boolValue]) {
72
+ requestConfiguration.ageRestrictedTreatment = GADAgeRestrictedTreatmentChild;
73
73
 
74
- NSNumber *tfuaTag = [self parseBooleanFromDict:config key:@"tagForUnderAgeOfConsent"];
75
- if (tfuaTag != nil) {
76
- requestConfiguration.tagForUnderAgeOfConsent = tfuaTag;
74
+ } else if (tfuaTag != nil && [tfuaTag boolValue]) {
75
+ requestConfiguration.ageRestrictedTreatment = GADAgeRestrictedTreatmentTeen;
76
+
77
+ } else if ((coppaTag != nil && ![coppaTag boolValue]) ||
78
+ (tfuaTag != nil && ![tfuaTag boolValue])) {
79
+ requestConfiguration.ageRestrictedTreatment = GADAgeRestrictedTreatmentUnspecified;
77
80
 
78
81
  }
79
82
 
@@ -62,6 +62,11 @@
62
62
  if (self.interstitialAd != nil) {
63
63
 
64
64
  [self.plugin fireEvent:@"document" event:@"on.interstitial.loaded" withData:nil];
65
+
66
+ if (self.isAutoShow) {
67
+ [self showInterstitialAd];
68
+ }
69
+
65
70
  return;
66
71
  }
67
72
 
@@ -131,6 +136,12 @@
131
136
  - (void)showInterstitialAd {
132
137
  if (self.interstitialAd == nil) return;
133
138
 
139
+ if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
140
+ NSString *jsonStr = @"{\"code\":\"APP_IN_BACKGROUND\", \"message\":\"Ad presentation blocked: Application is currently in the background.\"}";
141
+ [self.plugin fireEvent:@"document" event:@"on.interstitial.failed.show" withData:jsonStr];
142
+ return;
143
+ }
144
+
134
145
  [self.interstitialAd presentFromRootViewController:self.plugin.viewController];
135
146
  }
136
147
 
@@ -64,6 +64,11 @@
64
64
  if (self.rewardedAd != nil) {
65
65
 
66
66
  [self.plugin fireEvent:@"document" event:@"on.rewarded.loaded" withData:nil];
67
+
68
+ if (self.isAutoShow) {
69
+ [self showRewardedAd];
70
+ }
71
+
67
72
  return;
68
73
  }
69
74
 
@@ -133,6 +138,12 @@
133
138
  - (void)showRewardedAd {
134
139
  if (self.rewardedAd == nil) return;
135
140
 
141
+ if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
142
+ NSString *jsonStr = @"{\"code\":\"APP_IN_BACKGROUND\", \"message\":\"Ad presentation blocked: Application is currently in the background or inactive.\"}";
143
+ [self.plugin fireEvent:@"document" event:@"on.rewarded.failed.show" withData:jsonStr];
144
+ return;
145
+ }
146
+
136
147
  self.isRewardEarned = NO;
137
148
 
138
149
  [self.rewardedAd presentFromRootViewController:self.plugin.viewController
@@ -72,6 +72,12 @@
72
72
  CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"Ad Loaded (Cached)"];
73
73
  [self.plugin.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
74
74
  }
75
+
76
+ if (self.isAutoShow) {
77
+
78
+ [self showRewardedInterstitialAd:nil];
79
+ }
80
+
75
81
  return;
76
82
  }
77
83
 
@@ -144,6 +150,17 @@
144
150
  - (void)showRewardedInterstitialAd:(CDVInvokedUrlCommand *)command {
145
151
  if (self.rewardedInterstitialAd != nil) {
146
152
 
153
+ if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
154
+ NSString *jsonStr = @"{\"code\":\"APP_IN_BACKGROUND\", \"message\":\"Ad presentation blocked: Application is currently in the background or inactive.\"}";
155
+ [self.plugin fireEvent:@"document" event:@"on.rewardedInter.failed.show" withData:jsonStr];
156
+
157
+ if (command) {
158
+ CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Ad presentation blocked: Application is in background."];
159
+ [self.plugin.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
160
+ }
161
+ return;
162
+ }
163
+
147
164
  self.isRewardEarned = NO;
148
165
 
149
166
  [self.rewardedInterstitialAd presentFromRootViewController:self.plugin.viewController