@capacitor-community/admob 8.1.0 → 8.2.0-beta.pr483.shac8cc94ca69ee
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 +128 -323
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/getcapacitor/community/admob/AdMob.java +13 -3
- package/android/src/main/java/com/getcapacitor/community/admob/banner/BannerExecutor.java +261 -141
- package/android/src/main/java/com/getcapacitor/community/admob/helpers/FullscreenPluginCallback.kt +5 -1
- package/android/src/main/java/com/getcapacitor/community/admob/interstitial/AdInterstitialExecutor.java +27 -31
- package/android/src/main/java/com/getcapacitor/community/admob/interstitial/InterstitialAdCallbackAndListeners.kt +1 -1
- package/android/src/main/java/com/getcapacitor/community/admob/models/LoadPluginEventNames.kt +2 -1
- package/android/src/main/java/com/getcapacitor/community/admob/rewarded/AdRewardExecutor.java +29 -33
- package/android/src/main/java/com/getcapacitor/community/admob/rewarded/RewardAdPluginEvents.kt +2 -1
- package/android/src/main/java/com/getcapacitor/community/admob/rewarded/RewardedAdCallbackAndListeners.kt +1 -1
- package/android/src/main/java/com/getcapacitor/community/admob/rewardedinterstitial/AdRewardInterstitialExecutor.java +29 -37
- package/android/src/main/java/com/getcapacitor/community/admob/rewardedinterstitial/RewardedInterstitialAdCallbackAndListeners.kt +1 -1
- package/dist/docs.json +33 -3
- package/dist/esm/interstitial/interstitial-definitions.interface.d.ts +3 -0
- package/dist/esm/reward/reward-ad-plugin-events.enum.d.ts +4 -0
- package/dist/esm/reward/reward-ad-plugin-events.enum.js +4 -0
- package/dist/esm/reward/reward-ad-plugin-events.enum.js.map +1 -1
- package/dist/esm/reward/reward-definitions.interface.d.ts +8 -0
- package/dist/esm/reward-interstitial/reward-interstitial-definitions.interface.d.ts +3 -0
- package/dist/plugin.cjs.js +4 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +4 -0
- package/dist/plugin.js.map +1 -1
- package/docs/app-open.md +53 -0
- package/docs/banner.md +100 -0
- package/docs/configuration.md +30 -0
- package/docs/consent.md +80 -0
- package/docs/events.md +76 -0
- package/docs/interstitial.md +47 -0
- package/docs/migration.md +144 -0
- package/docs/rewarded.md +148 -0
- package/docs/testing.md +67 -0
- package/ios/Sources/AdMobPlugin/AdMobPlugin.swift +4 -1
- package/ios/Sources/AdMobPlugin/AppOpen/AppOpenAdManager.swift +1 -1
- package/ios/Sources/AdMobPlugin/Banner/BannerExecutor.swift +1 -1
- package/ios/Sources/AdMobPlugin/Interstitial/AdInterstitialExecutor.swift +3 -3
- package/ios/Sources/AdMobPlugin/Rewarded/AdRewardExecutor.swift +7 -3
- package/ios/Sources/AdMobPlugin/Rewarded/RewardAdPluginEvents.swift +1 -0
- package/ios/Sources/AdMobPlugin/RewardedInterstitial/AdRewardInterstitialExecutor.swift +3 -3
- package/package.json +3 -1
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Migration Guide
|
|
2
|
+
|
|
3
|
+
## Changes in 8.2.0
|
|
4
|
+
|
|
5
|
+
### Capacitor 8.5 or later is required
|
|
6
|
+
|
|
7
|
+
Update `@capacitor/core`, `@capacitor/cli`, and the native platform packages you use (`@capacitor/android` / `@capacitor/ios`) to 8.5 or later within v8, then run `npx cap sync`.
|
|
8
|
+
|
|
9
|
+
Older Capacitor versions can consume Android window insets before they reach a banner. Update Capacitor to use its current safe-area handling. Follow the [Capacitor 8.5 update guide](https://capacitorjs.com/docs/updating/8-5) for native project migration steps.
|
|
10
|
+
|
|
11
|
+
### Android initialization can reject
|
|
12
|
+
|
|
13
|
+
`AdMob.initialize()` now waits for the native banner parent view. If it does not appear within 5 seconds, initialization rejects; an unavailable activity/content view can fail immediately. This also applies to apps that only use full-screen ads. Previously, a missing child view could let initialization resolve and cause later banner requests to crash.
|
|
14
|
+
|
|
15
|
+
Handle initialization errors without blocking app startup. Retry when the native view is available. See [Configuration](https://docs.rdlabo.dev/projects/capacitor-admob/docs/configuration) for an example.
|
|
16
|
+
|
|
17
|
+
### iOS revenue values now use micros
|
|
18
|
+
|
|
19
|
+
The `valueMicros` field now correctly reports millionths of a currency unit for banners, interstitials, rewarded ads, rewarded interstitials, and app-open ads. For example, a value of `0.0012` currency units previously produced `0`; it now produces `1200`. Android values and event names are unchanged.
|
|
20
|
+
|
|
21
|
+
Divide `valueMicros` by `1_000_000` to obtain currency units on either platform. Review any iOS-specific workarounds in your analytics pipeline. Historical iOS values were truncated before conversion, so multiplying those stored values cannot recover the lost fractional revenue.
|
|
22
|
+
|
|
23
|
+
### Consent before SDK initialization
|
|
24
|
+
|
|
25
|
+
On iOS, `showConsentForm()` and `showPrivacyOptionsForm()` can now be called before `AdMob.initialize()`, matching Android. Request consent information, present a form if required, then initialize the Mobile Ads SDK and load ads only when `canRequestAds` is true. See [Consent](https://docs.rdlabo.dev/projects/capacitor-admob/docs/consent) for the complete sequence. Existing initialize-first integrations remain callable, but should adopt this order.
|
|
26
|
+
|
|
27
|
+
### Ad load errors preserve native codes
|
|
28
|
+
|
|
29
|
+
`prepareInterstitial()`, `prepareRewardVideoAd()`, and `prepareRewardInterstitialAd()` now reject SDK load failures with a string `code` and the native error message. Codes are platform-specific, not normalized across Android and iOS. `FailedToLoad` event codes remain numbers; on iOS they now contain the actual SDK code instead of a fixed `0`.
|
|
30
|
+
|
|
31
|
+
Update error handlers that match the iOS message `Loading failed` or assume an event code of `0`. Use the platform's SDK error definitions when handling no-fill and other failures.
|
|
32
|
+
|
|
33
|
+
### Rewarded ad click event
|
|
34
|
+
|
|
35
|
+
`RewardAdPluginEvents.adClicked` is a new optional listener for rewarded ads on Android and iOS. Its event string is `onRewardedVideoAdClicked`. Clicks are separate from earned rewards; continue granting rewards only from the `Rewarded` event or the show result, once. See [Rewarded Ads](https://docs.rdlabo.dev/projects/capacitor-admob/docs/rewarded).
|
|
36
|
+
|
|
37
|
+
### AGP 9 build compatibility
|
|
38
|
+
|
|
39
|
+
The Android library now references `proguard-android-optimize.txt`, avoiding AGP 9's rejection of the older default file. This does not enable library minification or upgrade your project's AGP. Other AGP 9 migration steps still apply to the host app.
|
|
40
|
+
|
|
41
|
+
The version-by-version steps under “Breaking changes from earlier versions” apply to releases before v8.
|
|
42
|
+
|
|
43
|
+
## Google Mobile Ads SDK versions
|
|
44
|
+
|
|
45
|
+
This major version keeps Google Mobile Ads SDK APIs that are deprecated but still supported. Replacing them can change banner sizing and age-restricted treatment, so that work waits for the next major.
|
|
46
|
+
|
|
47
|
+
Google's [Next-Gen SDK for Android](https://developers.google.com/admob/android/next-gen) also waits for the next major: it changes SDK initialization, ad requests, and mediation.
|
|
48
|
+
|
|
49
|
+
Pinned versions: Android 25.4.x, iOS 13.6.0 (Swift Package Manager and CocoaPods). CocoaPods support is planned to be removed in the next major.
|
|
50
|
+
|
|
51
|
+
## Breaking changes from earlier versions
|
|
52
|
+
|
|
53
|
+
### 1.1.0
|
|
54
|
+
|
|
55
|
+
- Prepare for iOS 14+
|
|
56
|
+
- In file `ios/App/App/AppDelegate.swift` remove the following:
|
|
57
|
+
|
|
58
|
+
```diff
|
|
59
|
+
- import GoogleMobileAds
|
|
60
|
+
|
|
61
|
+
@UIApplicationMain
|
|
62
|
+
class AppDelegate: UIResponder, UIApplicationDelegate {
|
|
63
|
+
|
|
64
|
+
var window: UIWindow?
|
|
65
|
+
|
|
66
|
+
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
|
67
|
+
- // Override point for customization after application launch.
|
|
68
|
+
- GADMobileAds.sharedInstance().start(completionHandler: nil)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 0.2.13
|
|
72
|
+
|
|
73
|
+
- isTest: 'LIVE' | 'TESTING' => boolean
|
|
74
|
+
|
|
75
|
+
### 0.2.12
|
|
76
|
+
|
|
77
|
+
**app.component.ts**
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import { Plugins } from '@capacitor/core';
|
|
81
|
+
|
|
82
|
+
const { AdMob } = Plugins;
|
|
83
|
+
|
|
84
|
+
@Component({
|
|
85
|
+
selector: 'app-root',
|
|
86
|
+
templateUrl: 'app.component.html',
|
|
87
|
+
styleUrls: ['app.component.scss'],
|
|
88
|
+
})
|
|
89
|
+
export class AppComponent {
|
|
90
|
+
constructor() {
|
|
91
|
+
// Initialize AdMob for your Application
|
|
92
|
+
+AdMob.initialize('[APP_ID]');
|
|
93
|
+
-AdMob.initialize();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**admob.component.ts**
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import { Plugins } from '@capacitor/core';
|
|
102
|
+
import { AdOptions, AdSize, AdPosition } from '@rdlabo/capacitor-admob';
|
|
103
|
+
|
|
104
|
+
const { AdMob } = Plugins;
|
|
105
|
+
|
|
106
|
+
@Component({
|
|
107
|
+
selector: 'admob',
|
|
108
|
+
templateUrl: 'admob.component.html',
|
|
109
|
+
styleUrls: ['admob.component.scss']
|
|
110
|
+
})
|
|
111
|
+
export class AdMobComponent {
|
|
112
|
+
|
|
113
|
+
const options: AdOptions = {
|
|
114
|
+
adId: 'YOUR ADID',
|
|
115
|
+
adSize: AdSize.BANNER,
|
|
116
|
+
position: AdPosition.BOTTOM_CENTER,
|
|
117
|
+
- margin: '0',
|
|
118
|
+
+ margin: 0,
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
constructor(){
|
|
122
|
+
// Show Banner Ad
|
|
123
|
+
AdMob.showBanner(this.options)
|
|
124
|
+
.then(
|
|
125
|
+
(value) => {
|
|
126
|
+
console.log(value); // true
|
|
127
|
+
},
|
|
128
|
+
(error) => {
|
|
129
|
+
console.error(error); // show error
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
// Subscibe Banner Event Listener
|
|
134
|
+
AdMob.addListener('onAdLoaded', (info: boolean) => {
|
|
135
|
+
console.log("Banner Ad Loaded");
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
+ // Get Banner Size
|
|
139
|
+
+ AdMob.addListener('onAdSize', (info: boolean) => {
|
|
140
|
+
+ console.log(info);
|
|
141
|
+
+ });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
package/docs/rewarded.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Rewarded Ads
|
|
2
|
+
|
|
3
|
+
Rewarded ads let you give in-app items for interacting with video ads, playable ads, or surveys. Google's rewarded guides for [Android](https://developers.google.com/admob/android/rewarded) and [iOS](https://developers.google.com/admob/ios/rewarded) explain the format.
|
|
4
|
+
|
|
5
|
+
Treat rewarded ads as a reward flow, not as another non-rewarded interstitial. Call this after [initialize](https://docs.rdlabo.dev/projects/capacitor-admob/docs/configuration) and [consent](https://docs.rdlabo.dev/projects/capacitor-admob/docs/consent). Grant the reward only from the returned result or the `Rewarded` event, not from `Dismissed`.
|
|
6
|
+
|
|
7
|
+
## Rewarded video
|
|
8
|
+
|
|
9
|
+
Use a rewarded ad for a dedicated reward flow.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import {
|
|
13
|
+
AdLoadInfo,
|
|
14
|
+
AdMob,
|
|
15
|
+
AdMobRevenueData,
|
|
16
|
+
AdMobRewardItem,
|
|
17
|
+
RewardAdOptions,
|
|
18
|
+
RewardAdPluginEvents,
|
|
19
|
+
} from '@capacitor-community/admob';
|
|
20
|
+
|
|
21
|
+
await AdMob.addListener(RewardAdPluginEvents.Loaded, (info: AdLoadInfo) => {
|
|
22
|
+
console.log('Rewarded ad loaded', info.adUnitId);
|
|
23
|
+
});
|
|
24
|
+
await AdMob.addListener(RewardAdPluginEvents.FailedToLoad, console.error);
|
|
25
|
+
await AdMob.addListener(RewardAdPluginEvents.Rewarded, (reward: AdMobRewardItem) => {
|
|
26
|
+
console.log('Reward earned', reward.amount, reward.type);
|
|
27
|
+
});
|
|
28
|
+
await AdMob.addListener(RewardAdPluginEvents.AdImpression, (data: AdMobRevenueData) => {
|
|
29
|
+
console.log(data);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const options: RewardAdOptions = {
|
|
33
|
+
adId: 'YOUR_AD_UNIT_ID',
|
|
34
|
+
// isTesting: true,
|
|
35
|
+
// npa: true,
|
|
36
|
+
// immersiveMode: true,
|
|
37
|
+
// ssv: {
|
|
38
|
+
// userId: 'USER_ID',
|
|
39
|
+
// customData: JSON.stringify({ placement: 'bonus' }),
|
|
40
|
+
// },
|
|
41
|
+
};
|
|
42
|
+
await AdMob.prepareRewardVideoAd(options);
|
|
43
|
+
const rewardItem = await AdMob.showRewardVideoAd();
|
|
44
|
+
// Grant the reward once, using this result or the Rewarded event — not both.
|
|
45
|
+
console.log(rewardItem);
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
<!-- !::prepareRewardVideoAd:: -->
|
|
49
|
+
|
|
50
|
+
<!-- !::showRewardVideoAd:: -->
|
|
51
|
+
|
|
52
|
+
<!-- !::RewardAdOptions:: -->
|
|
53
|
+
|
|
54
|
+
<!-- !::AdMobRewardItem:: -->
|
|
55
|
+
|
|
56
|
+
When no `adId` is passed to `showRewardVideoAd()`, the most recently prepared ad is shown.
|
|
57
|
+
|
|
58
|
+
### Click events (since 8.2.0)
|
|
59
|
+
|
|
60
|
+
Register `adClicked` before showing a rewarded ad. This forwards clicks recorded by the SDK, including after a reward is earned while the ad remains displayed. It does not indicate that a reward was earned and does not apply to rewarded interstitials.
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
const clickListener = await AdMob.addListener(RewardAdPluginEvents.adClicked, () => {
|
|
64
|
+
console.log('Rewarded ad clicked');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// When the owning screen is destroyed:
|
|
68
|
+
await clickListener.remove();
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Prepare more than one ad
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
await AdMob.prepareRewardVideoAd({ adId: 'ca-app-pub-xxx/reward-1' });
|
|
75
|
+
await AdMob.prepareRewardVideoAd({ adId: 'ca-app-pub-xxx/reward-2' });
|
|
76
|
+
|
|
77
|
+
const reward = await AdMob.showRewardVideoAd({ adId: 'ca-app-pub-xxx/reward-1' });
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Rewarded interstitial
|
|
81
|
+
|
|
82
|
+
Rewarded interstitial ads are incentivized full-screen ads that appear during natural app transitions. Unlike rewarded video, the user does not opt in first. Google's rewarded interstitial guides for [Android](https://developers.google.com/admob/android/rewarded-interstitial) and [iOS](https://developers.google.com/admob/ios/rewarded-interstitial) explain the format.
|
|
83
|
+
|
|
84
|
+
Use a rewarded interstitial when the rewarded experience belongs at a natural transition in the app.
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
import {
|
|
88
|
+
AdMob,
|
|
89
|
+
AdMobRewardInterstitialItem,
|
|
90
|
+
RewardInterstitialAdOptions,
|
|
91
|
+
RewardInterstitialAdPluginEvents,
|
|
92
|
+
} from '@capacitor-community/admob';
|
|
93
|
+
|
|
94
|
+
await AdMob.addListener(RewardInterstitialAdPluginEvents.FailedToLoad, console.error);
|
|
95
|
+
|
|
96
|
+
const options: RewardInterstitialAdOptions = {
|
|
97
|
+
adId: 'YOUR_AD_UNIT_ID',
|
|
98
|
+
};
|
|
99
|
+
const { adUnitId } = await AdMob.prepareRewardInterstitialAd(options);
|
|
100
|
+
const rewardItem: AdMobRewardInterstitialItem = await AdMob.showRewardInterstitialAd({
|
|
101
|
+
adId: adUnitId,
|
|
102
|
+
});
|
|
103
|
+
console.log(rewardItem);
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
<!-- !::prepareRewardInterstitialAd:: -->
|
|
107
|
+
|
|
108
|
+
<!-- !::showRewardInterstitialAd:: -->
|
|
109
|
+
|
|
110
|
+
<!-- !::RewardInterstitialAdOptions:: -->
|
|
111
|
+
|
|
112
|
+
<!-- !::AdMobRewardInterstitialItem:: -->
|
|
113
|
+
|
|
114
|
+
See [Testing](https://docs.rdlabo.dev/projects/capacitor-admob/docs/testing) for `isTesting`.
|
|
115
|
+
|
|
116
|
+
## Server-side verification
|
|
117
|
+
|
|
118
|
+
Server-side verification (SSV) lets your backend confirm that a reward was earned. See Google's [SSV documentation](https://support.google.com/admob/answer/9603226). Callbacks fire only for production ads; test ads do not invoke your SSV endpoint.
|
|
119
|
+
|
|
120
|
+
For local validation of the `ssv` payload, you can send a mock request after `RewardAdPluginEvents.Rewarded`. Replace `ENVIRONMENT_IS_DEVELOPMENT` with your own development flag:
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
const userId = 'USER_ID';
|
|
124
|
+
const customData = JSON.stringify({ placement: 'bonus' });
|
|
125
|
+
|
|
126
|
+
await AdMob.addListener(RewardAdPluginEvents.Rewarded, async () => {
|
|
127
|
+
if (!ENVIRONMENT_IS_DEVELOPMENT) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const params = new URLSearchParams({
|
|
132
|
+
ad_network: 'TEST',
|
|
133
|
+
ad_unit: 'TEST',
|
|
134
|
+
custom_data: customData,
|
|
135
|
+
reward_amount: 'TEST',
|
|
136
|
+
reward_item: 'TEST',
|
|
137
|
+
timestamp: 'TEST',
|
|
138
|
+
transaction_id: 'TEST',
|
|
139
|
+
user_id: userId,
|
|
140
|
+
signature: 'TEST',
|
|
141
|
+
key_id: 'TEST',
|
|
142
|
+
});
|
|
143
|
+
await fetch(`https://your-staging-ssv-endpoint?${params.toString()}`);
|
|
144
|
+
} catch (err) {
|
|
145
|
+
console.error(err);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
```
|
package/docs/testing.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Testing
|
|
2
|
+
|
|
3
|
+
Use test ads during development so you can click ads without charging advertisers or flagging the account for invalid traffic. Google's test ads guides for [Android](https://developers.google.com/admob/android/test-ads) and [iOS](https://developers.google.com/admob/ios/test-ads) explain demo ad units and test devices.
|
|
4
|
+
|
|
5
|
+
This plugin can request those demo units or register a device through `initialize`.
|
|
6
|
+
|
|
7
|
+
## Demo ad units
|
|
8
|
+
|
|
9
|
+
Google provides [demo ad units](https://developers.google.com/admob/android/test-ads#demo_ad_units) that always return test ads. Prefer these during development. This plugin supports native iOS and Android only—use the matching platform ID.
|
|
10
|
+
|
|
11
|
+
Banner demo units used by this plugin and its demo:
|
|
12
|
+
|
|
13
|
+
| Platform | Banner `adId` |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| Android | `ca-app-pub-3940256099942544/6300978111` |
|
|
16
|
+
| iOS | `ca-app-pub-3940256099942544/2934735716` |
|
|
17
|
+
|
|
18
|
+
Other format demo IDs are listed in Google's test-ads guides linked above. You can also set `isTesting: true` on banner, interstitial, rewarded, and rewarded interstitial requests. App Open ads have no `isTesting` option; pass a demo ad unit as `adId`.
|
|
19
|
+
|
|
20
|
+
## Test devices
|
|
21
|
+
|
|
22
|
+
To request production-like ads on a physical device without generating invalid traffic, register the device with `AdMob.initialize()`:
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
await AdMob.initialize({
|
|
26
|
+
testingDevices: ['YOUR_TEST_DEVICE_ID'],
|
|
27
|
+
initializeForTesting: true,
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
<!-- !::initialize:: -->
|
|
32
|
+
|
|
33
|
+
<!-- !::AdMobInitializationOptions:: -->
|
|
34
|
+
|
|
35
|
+
Find the device ID in the native logs after the first ad request:
|
|
36
|
+
|
|
37
|
+
- Android: Logcat, typically on the `Ads` tag (`Use RequestConfiguration.Builder.setTestDeviceIds(...)`).
|
|
38
|
+
- iOS: Xcode console (`To get test ads on this device, set:`).
|
|
39
|
+
|
|
40
|
+
See Google's [enable test devices](https://developers.google.com/admob/android/test-ads#enable_test_devices) guide.
|
|
41
|
+
|
|
42
|
+
## Consent debug geography
|
|
43
|
+
|
|
44
|
+
On a real device, set `debugGeography` and include the device ID in `testDeviceIdentifiers`. `EEA` makes the form behave as if the device were in the European Economic Area, so you can test GDPR messaging. Use this only on registered test devices.
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { AdMob, AdmobConsentDebugGeography } from '@capacitor-community/admob';
|
|
48
|
+
|
|
49
|
+
const consentInfo = await AdMob.requestConsentInfo({
|
|
50
|
+
debugGeography: AdmobConsentDebugGeography.EEA,
|
|
51
|
+
testDeviceIdentifiers: ['YOUR_TEST_DEVICE_ID'],
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
<!-- !::requestConsentInfo:: -->
|
|
56
|
+
|
|
57
|
+
<!-- !::AdmobConsentRequestOptions:: -->
|
|
58
|
+
|
|
59
|
+
<!-- !::AdmobConsentDebugGeography:: -->
|
|
60
|
+
|
|
61
|
+
If you decline consent in the test form (Manage → Confirm Choices), ads may not load. That is expected in a test environment and does not predict production behavior after a user consents.
|
|
62
|
+
|
|
63
|
+
`resetConsentInfo()` is for tests only. See [Consent](https://docs.rdlabo.dev/projects/capacitor-admob/docs/consent).
|
|
64
|
+
|
|
65
|
+
## Server-side verification
|
|
66
|
+
|
|
67
|
+
Server-side verification (SSV) callbacks fire only for production ads. Test ads will not hit your SSV endpoint. For a mock request example, see [Rewarded Ads](https://docs.rdlabo.dev/projects/capacitor-admob/docs/rewarded).
|
|
@@ -65,6 +65,10 @@ public class AdMobPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
65
65
|
private let adRewardInterstitialExecutor = AdRewardInterstitialExecutor()
|
|
66
66
|
private let consentExecutor = ConsentExecutor()
|
|
67
67
|
|
|
68
|
+
public override func load() {
|
|
69
|
+
self.consentExecutor.plugin = self
|
|
70
|
+
}
|
|
71
|
+
|
|
68
72
|
/**
|
|
69
73
|
* Enable SKAdNetwork to track conversions
|
|
70
74
|
* https://developers.google.com/admob/ios/ios14
|
|
@@ -75,7 +79,6 @@ public class AdMobPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
75
79
|
self.adRewardExecutor.plugin = self
|
|
76
80
|
self.adRewardInterstitialExecutor.plugin = self
|
|
77
81
|
self.adInterstitialExecutor.plugin = self
|
|
78
|
-
self.consentExecutor.plugin = self
|
|
79
82
|
self.setRequestConfiguration(call)
|
|
80
83
|
|
|
81
84
|
MobileAds.shared.start(completionHandler: nil)
|
|
@@ -38,7 +38,7 @@ import UIKit
|
|
|
38
38
|
let networkName = ad.responseInfo.loadedAdNetworkResponseInfo?.adNetworkClassName ?? ""
|
|
39
39
|
let impressionId = ad.responseInfo.responseIdentifier ?? ""
|
|
40
40
|
onPaidEvent(
|
|
41
|
-
adValue.value.int64Value,
|
|
41
|
+
adValue.value.multiplying(byPowerOf10: 6).int64Value,
|
|
42
42
|
adValue.currencyCode,
|
|
43
43
|
adValue.precision.rawValue,
|
|
44
44
|
networkName,
|
|
@@ -55,7 +55,7 @@ class BannerExecutor: NSObject, BannerViewDelegate {
|
|
|
55
55
|
let impressionId = self.bannerView.responseInfo?.responseIdentifier ?? ""
|
|
56
56
|
self.plugin?.notifyListeners(BannerAdPluginEvents.AdPaid.rawValue, data: [
|
|
57
57
|
"adUnitId": self.bannerView.adUnitID ?? "",
|
|
58
|
-
"valueMicros": adValue.value.int64Value,
|
|
58
|
+
"valueMicros": adValue.value.multiplying(byPowerOf10: 6).int64Value,
|
|
59
59
|
"currencyCode": adValue.currencyCode,
|
|
60
60
|
"precision": adValue.precision.rawValue,
|
|
61
61
|
"networkName": networkName,
|
|
@@ -16,10 +16,10 @@ class AdInterstitialExecutor: NSObject, FullScreenContentDelegate {
|
|
|
16
16
|
if let error = error {
|
|
17
17
|
NSLog("Interstitial ad failed to load with error: \(error.localizedDescription)")
|
|
18
18
|
self.plugin?.notifyListeners(InterstitialAdPluginEvents.FailedToLoad.rawValue, data: [
|
|
19
|
-
"code":
|
|
19
|
+
"code": (error as NSError).code,
|
|
20
20
|
"message": error.localizedDescription
|
|
21
21
|
])
|
|
22
|
-
call.reject(
|
|
22
|
+
call.reject(error.localizedDescription, String((error as NSError).code), error)
|
|
23
23
|
return
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -30,7 +30,7 @@ class AdInterstitialExecutor: NSObject, FullScreenContentDelegate {
|
|
|
30
30
|
let impressionId = ad.responseInfo.responseIdentifier ?? ""
|
|
31
31
|
self.plugin?.notifyListeners(InterstitialAdPluginEvents.AdImpression.rawValue, data: [
|
|
32
32
|
"adUnitId": adUnitID,
|
|
33
|
-
"valueMicros": adValue.value.int64Value,
|
|
33
|
+
"valueMicros": adValue.value.multiplying(byPowerOf10: 6).int64Value,
|
|
34
34
|
"currencyCode": adValue.currencyCode,
|
|
35
35
|
"precision": adValue.precision.rawValue,
|
|
36
36
|
"networkName": networkName,
|
|
@@ -16,10 +16,10 @@ class AdRewardExecutor: NSObject, FullScreenContentDelegate {
|
|
|
16
16
|
if let error = error {
|
|
17
17
|
NSLog("Rewarded ad failed to load with error: \(error.localizedDescription)")
|
|
18
18
|
self.plugin?.notifyListeners(RewardAdPluginEvents.FailedToLoad.rawValue, data: [
|
|
19
|
-
"code":
|
|
19
|
+
"code": (error as NSError).code,
|
|
20
20
|
"message": error.localizedDescription
|
|
21
21
|
])
|
|
22
|
-
call.reject(
|
|
22
|
+
call.reject(error.localizedDescription, String((error as NSError).code), error)
|
|
23
23
|
return
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -50,7 +50,7 @@ class AdRewardExecutor: NSObject, FullScreenContentDelegate {
|
|
|
50
50
|
let impressionId = ad.responseInfo.responseIdentifier ?? ""
|
|
51
51
|
self.plugin?.notifyListeners(RewardAdPluginEvents.AdImpression.rawValue, data: [
|
|
52
52
|
"adUnitId": adUnitID,
|
|
53
|
-
"valueMicros": adValue.value.int64Value,
|
|
53
|
+
"valueMicros": adValue.value.multiplying(byPowerOf10: 6).int64Value,
|
|
54
54
|
"currencyCode": adValue.currencyCode,
|
|
55
55
|
"precision": adValue.precision.rawValue,
|
|
56
56
|
"networkName": networkName,
|
|
@@ -110,6 +110,10 @@ class AdRewardExecutor: NSObject, FullScreenContentDelegate {
|
|
|
110
110
|
self.plugin?.notifyListeners(RewardAdPluginEvents.Showed.rawValue, data: [:])
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
func adDidRecordClick(_ advertisement: FullScreenPresentingAd) {
|
|
114
|
+
self.plugin?.notifyListeners(RewardAdPluginEvents.adClicked.rawValue, data: [:])
|
|
115
|
+
}
|
|
116
|
+
|
|
113
117
|
func adDidDismissFullScreenContent(_ ad: FullScreenPresentingAd) {
|
|
114
118
|
removeCurrentlyShowingAd()
|
|
115
119
|
NSLog("RewardFullScreenDelegate Ad did dismiss full screen content.")
|
|
@@ -16,10 +16,10 @@ class AdRewardInterstitialExecutor: NSObject, FullScreenContentDelegate {
|
|
|
16
16
|
if let error = error {
|
|
17
17
|
NSLog("Rewarded interstitial ad failed to load with error: \(error.localizedDescription)")
|
|
18
18
|
self.plugin?.notifyListeners(RewardInterstitialAdPluginEvents.FailedToLoad.rawValue, data: [
|
|
19
|
-
"code":
|
|
19
|
+
"code": (error as NSError).code,
|
|
20
20
|
"message": error.localizedDescription
|
|
21
21
|
])
|
|
22
|
-
call.reject(
|
|
22
|
+
call.reject(error.localizedDescription, String((error as NSError).code), error)
|
|
23
23
|
return
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -50,7 +50,7 @@ class AdRewardInterstitialExecutor: NSObject, FullScreenContentDelegate {
|
|
|
50
50
|
let impressionId = ad.responseInfo.responseIdentifier ?? ""
|
|
51
51
|
self.plugin?.notifyListeners(RewardInterstitialAdPluginEvents.AdImpression.rawValue, data: [
|
|
52
52
|
"adUnitId": adUnitID,
|
|
53
|
-
"valueMicros": adValue.value.int64Value,
|
|
53
|
+
"valueMicros": adValue.value.multiplying(byPowerOf10: 6).int64Value,
|
|
54
54
|
"currencyCode": adValue.currencyCode,
|
|
55
55
|
"precision": adValue.precision.rawValue,
|
|
56
56
|
"networkName": networkName,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capacitor-community/admob",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "8.
|
|
4
|
+
"version": "8.2.0-beta.pr483.shac8cc94ca69ee",
|
|
5
5
|
"description": "A native plugin for AdMob",
|
|
6
6
|
"main": "dist/plugin.cjs.js",
|
|
7
7
|
"module": "dist/esm/index.js",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"android/src/main/",
|
|
15
15
|
"android/build.gradle",
|
|
16
16
|
"dist/",
|
|
17
|
+
"docs/",
|
|
17
18
|
"ios/Sources",
|
|
18
19
|
"ios/Tests",
|
|
19
20
|
"Package.swift",
|
|
@@ -28,6 +29,7 @@
|
|
|
28
29
|
"bugs": {
|
|
29
30
|
"url": "git@github.com:capacitor-community/admob.git/issues"
|
|
30
31
|
},
|
|
32
|
+
"homepage": "https://docs.rdlabo.dev/projects/capacitor-admob",
|
|
31
33
|
"scripts": {
|
|
32
34
|
"verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
|
|
33
35
|
"verify:ios": "xcodebuild -scheme CapacitorCommunityAdmob -destination generic/platform=iOS",
|