cordova-plugin-admob-nextgen 2.0.3 → 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 +10 -27
- package/capacitor-hook-admob-ids.js +2 -2
- package/package.json +1 -1
- package/plugin.xml +2 -2
- package/src/android/ConsentExecutor.java +10 -2
- package/src/ios/AdMobNextGen.m +10 -8
- package/src/ios/BannerExecutor.m +132 -66
- package/src/ios/ConsentExecutor.m +12 -2
- package/src/ios/GlobalSettingsExecutor.m +9 -6
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
package/plugin.xml
CHANGED
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
|
|
55
55
|
</platform>
|
|
56
56
|
|
|
57
|
-
<preference name="NEXT_GEN_SDK_VERSION" default="1.
|
|
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.
|
|
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",
|
|
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 ==
|
|
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.";
|
package/src/ios/AdMobNextGen.m
CHANGED
|
@@ -54,14 +54,16 @@
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (
|
|
63
|
-
|
|
64
|
-
|
|
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
|
|
package/src/ios/BannerExecutor.m
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
return;
|
|
329
|
+
UIViewController *rootVC = self.plugin.viewController;
|
|
330
|
+
UIView *webView = self.plugin.webView;
|
|
331
|
+
if (!rootVC || !webView) return;
|
|
266
332
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
(window) ? window.safeAreaInsets : UIEdgeInsetsZero;
|
|
333
|
+
UIWindow *window = [self getKeyWindow];
|
|
334
|
+
if (!window) return;
|
|
270
335
|
|
|
271
|
-
|
|
272
|
-
CGFloat screenW = UIScreen.mainScreen.bounds.size.width;
|
|
336
|
+
UIEdgeInsets safeArea = window.safeAreaInsets;
|
|
273
337
|
|
|
274
|
-
|
|
275
|
-
|
|
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
|
-
|
|
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
|
-
|
|
282
|
-
self.activeBannerHeight > 0) {
|
|
344
|
+
CGRect fullScreenRect = CGRectMake(0, 0, screenW, screenH);
|
|
283
345
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
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
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
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
|
-
|
|
299
|
-
|
|
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
|
-
|
|
321
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
|