react-native-google-mobile-ads 11.1.1 → 11.3.0

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.
Files changed (145) hide show
  1. package/README.md +15 -0
  2. package/RNGoogleMobileAds.podspec +6 -2
  3. package/__tests__/banner.test.tsx +10 -0
  4. package/__tests__/googleMobileAds.test.ts +21 -0
  5. package/__tests__/interstitial.test.ts +22 -8
  6. package/android/build.gradle +8 -0
  7. package/android/src/main/java/io/invertase/googlemobileads/OnNativeEvent.kt +21 -0
  8. package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsBannerAdViewManager.java +21 -9
  9. package/android/src/main/java/io/invertase/googlemobileads/common/SharedUtils.java +17 -15
  10. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsAppOpenModule.m +4 -0
  11. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsAppOpenModule.swift +4 -0
  12. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsBannerComponent.h +4 -0
  13. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsBannerComponent.m +11 -2
  14. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsBannerView.h +30 -0
  15. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsBannerView.mm +220 -0
  16. package/ios/RNGoogleMobileAds/{RNGoogleMobileAdsBannerViewManager.m → RNGoogleMobileAdsBannerViewManager.mm} +19 -2
  17. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsCommon.h +5 -1
  18. package/ios/RNGoogleMobileAds/{RNGoogleMobileAdsCommon.m → RNGoogleMobileAdsCommon.mm} +4 -0
  19. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsConsentModule.m +13 -1
  20. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsFullScreenAd.swift +4 -0
  21. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsFullScreenContentDelegate.swift +4 -0
  22. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsInterstitialModule.m +4 -0
  23. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsInterstitialModule.swift +4 -0
  24. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsModule.h +9 -1
  25. package/ios/RNGoogleMobileAds/{RNGoogleMobileAdsModule.m → RNGoogleMobileAdsModule.mm} +52 -21
  26. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsRewardedInterstitialModule.m +4 -0
  27. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsRewardedInterstitialModule.swift +4 -0
  28. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsRewardedModule.m +4 -0
  29. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsRewardedModule.swift +4 -0
  30. package/jest.setup.ts +12 -1
  31. package/lib/commonjs/MobileAds.js +26 -31
  32. package/lib/commonjs/MobileAds.js.map +1 -1
  33. package/lib/commonjs/NativeGoogleMobileAdsModule.js +10 -0
  34. package/lib/commonjs/NativeGoogleMobileAdsModule.js.map +1 -0
  35. package/lib/commonjs/ads/AppOpenAd.js +1 -2
  36. package/lib/commonjs/ads/AppOpenAd.js.map +1 -1
  37. package/lib/commonjs/ads/BaseAd.js +11 -13
  38. package/lib/commonjs/ads/BaseAd.js.map +1 -1
  39. package/lib/commonjs/ads/GAMBannerAd.js +3 -5
  40. package/lib/commonjs/ads/GAMBannerAd.js.map +1 -1
  41. package/lib/commonjs/ads/GoogleMobileAdsBannerViewNativeComponent.js +16 -0
  42. package/lib/commonjs/ads/GoogleMobileAdsBannerViewNativeComponent.js.map +1 -0
  43. package/lib/commonjs/ads/InterstitialAd.js +1 -2
  44. package/lib/commonjs/ads/InterstitialAd.js.map +1 -1
  45. package/lib/commonjs/ads/MobileAd.js +8 -6
  46. package/lib/commonjs/ads/MobileAd.js.map +1 -1
  47. package/lib/commonjs/ads/RewardedAd.js +1 -2
  48. package/lib/commonjs/ads/RewardedAd.js.map +1 -1
  49. package/lib/commonjs/ads/RewardedInterstitialAd.js +1 -2
  50. package/lib/commonjs/ads/RewardedInterstitialAd.js.map +1 -1
  51. package/lib/commonjs/internal/GoogleMobileAdsNativeEventEmitter.js.map +1 -1
  52. package/lib/commonjs/version.js +1 -1
  53. package/lib/module/MobileAds.js +25 -31
  54. package/lib/module/MobileAds.js.map +1 -1
  55. package/lib/module/NativeGoogleMobileAdsModule.js +3 -0
  56. package/lib/module/NativeGoogleMobileAdsModule.js.map +1 -0
  57. package/lib/module/ads/AppOpenAd.js +1 -2
  58. package/lib/module/ads/AppOpenAd.js.map +1 -1
  59. package/lib/module/ads/BaseAd.js +9 -12
  60. package/lib/module/ads/BaseAd.js.map +1 -1
  61. package/lib/module/ads/GAMBannerAd.js +3 -5
  62. package/lib/module/ads/GAMBannerAd.js.map +1 -1
  63. package/lib/module/ads/GoogleMobileAdsBannerViewNativeComponent.js +7 -0
  64. package/lib/module/ads/GoogleMobileAdsBannerViewNativeComponent.js.map +1 -0
  65. package/lib/module/ads/InterstitialAd.js +1 -2
  66. package/lib/module/ads/InterstitialAd.js.map +1 -1
  67. package/lib/module/ads/MobileAd.js +8 -6
  68. package/lib/module/ads/MobileAd.js.map +1 -1
  69. package/lib/module/ads/RewardedAd.js +1 -2
  70. package/lib/module/ads/RewardedAd.js.map +1 -1
  71. package/lib/module/ads/RewardedInterstitialAd.js +1 -2
  72. package/lib/module/ads/RewardedInterstitialAd.js.map +1 -1
  73. package/lib/module/internal/GoogleMobileAdsNativeEventEmitter.js.map +1 -1
  74. package/lib/module/version.js +1 -1
  75. package/lib/typescript/MobileAds.d.ts +3 -4
  76. package/lib/typescript/MobileAds.d.ts.map +1 -1
  77. package/lib/typescript/NativeGoogleMobileAdsModule.d.ts +12 -0
  78. package/lib/typescript/NativeGoogleMobileAdsModule.d.ts.map +1 -0
  79. package/lib/typescript/ads/AppOpenAd.d.ts.map +1 -1
  80. package/lib/typescript/ads/BaseAd.d.ts +1 -33
  81. package/lib/typescript/ads/BaseAd.d.ts.map +1 -1
  82. package/lib/typescript/ads/GAMBannerAd.d.ts.map +1 -1
  83. package/lib/typescript/ads/GoogleMobileAdsBannerViewNativeComponent.d.ts +27 -0
  84. package/lib/typescript/ads/GoogleMobileAdsBannerViewNativeComponent.d.ts.map +1 -0
  85. package/lib/typescript/ads/InterstitialAd.d.ts.map +1 -1
  86. package/lib/typescript/ads/MobileAd.d.ts +6 -5
  87. package/lib/typescript/ads/MobileAd.d.ts.map +1 -1
  88. package/lib/typescript/ads/RewardedAd.d.ts.map +1 -1
  89. package/lib/typescript/ads/RewardedInterstitialAd.d.ts.map +1 -1
  90. package/lib/typescript/index.d.ts +1 -1
  91. package/lib/typescript/internal/GoogleMobileAdsNativeEventEmitter.d.ts +2 -1
  92. package/lib/typescript/internal/GoogleMobileAdsNativeEventEmitter.d.ts.map +1 -1
  93. package/lib/typescript/types/MobileAdsModule.interface.d.ts +0 -10
  94. package/lib/typescript/types/MobileAdsModule.interface.d.ts.map +1 -1
  95. package/lib/typescript/version.d.ts +1 -1
  96. package/package.json +9 -1
  97. package/src/MobileAds.ts +29 -62
  98. package/src/NativeGoogleMobileAdsModule.ts +14 -0
  99. package/src/ads/AppOpenAd.ts +7 -2
  100. package/src/ads/BaseAd.tsx +101 -116
  101. package/src/ads/GAMBannerAd.tsx +5 -8
  102. package/src/ads/GoogleMobileAdsBannerViewNativeComponent.ts +37 -0
  103. package/src/ads/InterstitialAd.ts +7 -2
  104. package/src/ads/MobileAd.ts +22 -10
  105. package/src/ads/RewardedAd.ts +7 -2
  106. package/src/ads/RewardedInterstitialAd.ts +1 -2
  107. package/src/internal/GoogleMobileAdsNativeEventEmitter.ts +1 -1
  108. package/src/types/MobileAdsModule.interface.ts +0 -13
  109. package/src/version.ts +1 -1
  110. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsBannerViewManager.h +0 -23
  111. package/lib/commonjs/internal/Module.js +0 -44
  112. package/lib/commonjs/internal/Module.js.map +0 -1
  113. package/lib/commonjs/internal/index.js +0 -44
  114. package/lib/commonjs/internal/index.js.map +0 -1
  115. package/lib/commonjs/internal/registry/nativeModule.js +0 -180
  116. package/lib/commonjs/internal/registry/nativeModule.js.map +0 -1
  117. package/lib/commonjs/types/GoogleMobileAdsNativeModule.js +0 -6
  118. package/lib/commonjs/types/GoogleMobileAdsNativeModule.js.map +0 -1
  119. package/lib/commonjs/types/Module.interface.js +0 -2
  120. package/lib/commonjs/types/Module.interface.js.map +0 -1
  121. package/lib/module/internal/Module.js +0 -54
  122. package/lib/module/internal/Module.js.map +0 -1
  123. package/lib/module/internal/index.js +0 -22
  124. package/lib/module/internal/index.js.map +0 -1
  125. package/lib/module/internal/registry/nativeModule.js +0 -174
  126. package/lib/module/internal/registry/nativeModule.js.map +0 -1
  127. package/lib/module/types/GoogleMobileAdsNativeModule.js +0 -2
  128. package/lib/module/types/GoogleMobileAdsNativeModule.js.map +0 -1
  129. package/lib/module/types/Module.interface.js +0 -2
  130. package/lib/module/types/Module.interface.js.map +0 -1
  131. package/lib/typescript/internal/Module.d.ts +0 -14
  132. package/lib/typescript/internal/Module.d.ts.map +0 -1
  133. package/lib/typescript/internal/index.d.ts +0 -5
  134. package/lib/typescript/internal/index.d.ts.map +0 -1
  135. package/lib/typescript/internal/registry/nativeModule.d.ts +0 -10
  136. package/lib/typescript/internal/registry/nativeModule.d.ts.map +0 -1
  137. package/lib/typescript/types/GoogleMobileAdsNativeModule.d.ts +0 -22
  138. package/lib/typescript/types/GoogleMobileAdsNativeModule.d.ts.map +0 -1
  139. package/lib/typescript/types/Module.interface.d.ts +0 -15
  140. package/lib/typescript/types/Module.interface.d.ts.map +0 -1
  141. package/src/internal/Module.ts +0 -58
  142. package/src/internal/index.ts +0 -21
  143. package/src/internal/registry/nativeModule.ts +0 -205
  144. package/src/types/GoogleMobileAdsNativeModule.ts +0 -26
  145. package/src/types/Module.interface.ts +0 -16
package/README.md CHANGED
@@ -30,6 +30,21 @@ React Native Google Mobile Ads is built with three key principals in mind;
30
30
  - 📄 **Well documented**
31
31
  - full reference & installation documentation alongside detailed guides and FAQs
32
32
 
33
+ ## Migrating to the New Architecture Status (backwards compatible)
34
+ This package can be used in both The Old and [The New Architecture](https://reactnative.dev/docs/the-new-architecture/landing-page).
35
+ When using The New Architecture, some legacy code will still be used though. See status below:
36
+
37
+ - **iOS**
38
+ - Mobile Ads SDK Methods (Turbo Native Module) 🟢🟢🟢🟢
39
+ - Banners (Fabric Native Component) 🟢🟢🟢🟢
40
+ - Full Screen Ads (Turbo Native Module) ⚪⚪⚪⚪
41
+ - User Messaging Platform (Turbo Native Module) ⚪⚪⚪⚪
42
+ - **Android**
43
+ - Mobile Ads SDK Methods (Turbo Native Module) ⚪⚪⚪⚪
44
+ - Banners (Fabric Native Component) ⚪⚪⚪⚪
45
+ - Full Screen Ads (Turbo Native Module) ⚪⚪⚪⚪
46
+ - User Messaging Platform (Turbo Native Module) ⚪⚪⚪⚪
47
+
33
48
  ## Documentation
34
49
 
35
50
  - [Installation](https://docs.page/invertase/react-native-google-mobile-ads)
@@ -18,11 +18,11 @@ Pod::Spec.new do |s|
18
18
  s.source = { :git => "#{package["repository"]["url"]}.git", :tag => "v#{s.version}" }
19
19
  s.social_media_url = 'http://twitter.com/invertaseio'
20
20
  s.ios.deployment_target = "10.0"
21
- s.source_files = 'ios/**/*.{h,m,swift}'
21
+ s.source_files = "ios/**/*.{h,m,mm,swift}"
22
22
  s.weak_frameworks = "AppTrackingTransparency"
23
23
 
24
24
  # React Native dependencies
25
- s.dependency 'React-Core'
25
+ install_modules_dependencies(s)
26
26
 
27
27
  # Other dependencies
28
28
  if defined?($RNGoogleUmpSDKVersion)
@@ -30,7 +30,9 @@ Pod::Spec.new do |s|
30
30
  google_ump_sdk_version = $RNGoogleUmpSDKVersion
31
31
  end
32
32
 
33
+ if !ENV['MAC_CATALYST']
33
34
  s.dependency 'GoogleUserMessagingPlatform', google_ump_sdk_version
35
+ end
34
36
 
35
37
  if defined?($RNGoogleMobileAdsSDKVersion)
36
38
  Pod::UI.puts "#{s.name}: Using user specified Google Mobile-Ads SDK version '#{$RNGoogleMobileAdsSDKVersion}'"
@@ -38,7 +40,9 @@ Pod::Spec.new do |s|
38
40
  end
39
41
 
40
42
  # AdMob dependencies
43
+ if !ENV['MAC_CATALYST']
41
44
  s.dependency 'Google-Mobile-Ads-SDK', google_mobile_ads_sdk_version
45
+ end
42
46
 
43
47
  if defined?($RNGoogleMobileAdsAsStaticFramework)
44
48
  Pod::UI.puts "#{s.name}: Using overridden static_framework value of '#{$RNGoogleMobileAdsAsStaticFramework}'"
@@ -26,4 +26,14 @@ describe('Google Mobile Ads Banner', function () {
26
26
  "BannerAd: 'size(s)' expected a valid BannerAdSize or custom size string.",
27
27
  );
28
28
  });
29
+
30
+ it('throws if requestOptions is invalid.', function () {
31
+ let errorMsg;
32
+ try {
33
+ render(<BannerAd unitId={MOCK_ID} size={BannerAdSize.BANNER} requestOptions={'options'} />);
34
+ } catch (e) {
35
+ errorMsg = e.message;
36
+ }
37
+ expect(errorMsg).toEqual("BannerAd: 'options' expected an object value");
38
+ });
29
39
  });
@@ -1,4 +1,5 @@
1
1
  import admob, { MaxAdContentRating } from '../src';
2
+ import RNGoogleMobileAdsModule from '../src/NativeGoogleMobileAdsModule';
2
3
 
3
4
  describe('Admob', function () {
4
5
  describe('setRequestConfiguration()', function () {
@@ -61,6 +62,26 @@ describe('Admob', function () {
61
62
  });
62
63
 
63
64
  describe('testDebugMenu', function () {
65
+ it('does call native initialize method', () => {
66
+ admob().initialize();
67
+ expect(RNGoogleMobileAdsModule.initialize).toBeCalledTimes(1);
68
+ });
69
+
70
+ it('does call native setRequestConfiguration method', () => {
71
+ admob().setRequestConfiguration({ tagForChildDirectedTreatment: true });
72
+ expect(RNGoogleMobileAdsModule.setRequestConfiguration).toBeCalledTimes(1);
73
+ });
74
+
75
+ it('does call native openAdInspector method', () => {
76
+ admob().openAdInspector();
77
+ expect(RNGoogleMobileAdsModule.openAdInspector).toBeCalledTimes(1);
78
+ });
79
+
80
+ it('does call native openDebugMenu method', () => {
81
+ admob().openDebugMenu('12345');
82
+ expect(RNGoogleMobileAdsModule.openDebugMenu).toBeCalledTimes(1);
83
+ });
84
+
64
85
  it('throws if adUnit is empty', function () {
65
86
  expect(() => {
66
87
  admob().openDebugMenu('');
@@ -34,17 +34,23 @@ describe('Google Mobile Ads Interstitial', function () {
34
34
  const ad = InterstitialAd.createForAdRequest('abc');
35
35
 
36
36
  ad.load();
37
- expect(NativeModules.RNGoogleMobileAdsModule.interstitialLoad).toBeCalledTimes(1);
37
+ expect(NativeModules.RNGoogleMobileAdsInterstitialModule.interstitialLoad).toBeCalledTimes(
38
+ 1,
39
+ );
38
40
  });
39
41
 
40
42
  it('does nothing if ad currently loading', () => {
41
43
  const ad = InterstitialAd.createForAdRequest('abc');
42
44
 
43
45
  ad.load();
44
- expect(NativeModules.RNGoogleMobileAdsModule.interstitialLoad).toBeCalledTimes(1);
46
+ expect(NativeModules.RNGoogleMobileAdsInterstitialModule.interstitialLoad).toBeCalledTimes(
47
+ 1,
48
+ );
45
49
 
46
50
  ad.load();
47
- expect(NativeModules.RNGoogleMobileAdsModule.interstitialLoad).toBeCalledTimes(1);
51
+ expect(NativeModules.RNGoogleMobileAdsInterstitialModule.interstitialLoad).toBeCalledTimes(
52
+ 1,
53
+ );
48
54
  });
49
55
 
50
56
  it('does nothing if ad is already loaded', () => {
@@ -54,33 +60,41 @@ describe('Google Mobile Ads Interstitial', function () {
54
60
  ad._handleAdEvent({ body: { type: AdEventType.LOADED } });
55
61
 
56
62
  ad.load();
57
- expect(NativeModules.RNGoogleMobileAdsModule.interstitialLoad).not.toBeCalled();
63
+ expect(NativeModules.RNGoogleMobileAdsInterstitialModule.interstitialLoad).not.toBeCalled();
58
64
  });
59
65
 
60
66
  it('can be called again after ad was closed', () => {
61
67
  const ad = InterstitialAd.createForAdRequest('abc');
62
68
 
63
69
  ad.load();
64
- expect(NativeModules.RNGoogleMobileAdsModule.interstitialLoad).toBeCalledTimes(1);
70
+ expect(NativeModules.RNGoogleMobileAdsInterstitialModule.interstitialLoad).toBeCalledTimes(
71
+ 1,
72
+ );
65
73
 
66
74
  // @ts-ignore
67
75
  ad._handleAdEvent({ body: { type: AdEventType.CLOSED } });
68
76
 
69
77
  ad.load();
70
- expect(NativeModules.RNGoogleMobileAdsModule.interstitialLoad).toBeCalledTimes(2);
78
+ expect(NativeModules.RNGoogleMobileAdsInterstitialModule.interstitialLoad).toBeCalledTimes(
79
+ 2,
80
+ );
71
81
  });
72
82
 
73
83
  it('can be called again after ad failed to load', () => {
74
84
  const ad = InterstitialAd.createForAdRequest('abc');
75
85
 
76
86
  ad.load();
77
- expect(NativeModules.RNGoogleMobileAdsModule.interstitialLoad).toBeCalledTimes(1);
87
+ expect(NativeModules.RNGoogleMobileAdsInterstitialModule.interstitialLoad).toBeCalledTimes(
88
+ 1,
89
+ );
78
90
 
79
91
  // @ts-ignore
80
92
  ad._handleAdEvent({ body: { type: AdEventType.ERROR } });
81
93
 
82
94
  ad.load();
83
- expect(NativeModules.RNGoogleMobileAdsModule.interstitialLoad).toBeCalledTimes(2);
95
+ expect(NativeModules.RNGoogleMobileAdsInterstitialModule.interstitialLoad).toBeCalledTimes(
96
+ 2,
97
+ );
84
98
  });
85
99
  });
86
100
 
@@ -41,6 +41,13 @@ def jsonMinSdk = packageJson['sdkVersions']['android']['minSdk']
41
41
  def jsonTargetSdk = packageJson['sdkVersions']['android']['targetSdk']
42
42
  def jsonCompileSdk = packageJson['sdkVersions']['android']['compileSdk']
43
43
  def jsonBuildTools = packageJson['sdkVersions']['android']['buildTools']
44
+ def isNewArchitectureEnabled() {
45
+ return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
46
+ }
47
+
48
+ if (isNewArchitectureEnabled()) {
49
+ apply plugin: "com.facebook.react"
50
+ }
44
51
 
45
52
  project.ext {
46
53
  set('react-native', [
@@ -100,6 +107,7 @@ android {
100
107
  appJSONGoogleMobileAdsOptimizeInitialization : appJSONGoogleMobileAdsOptimizeInitializationBool,
101
108
  appJSONGoogleMobileAdsOptimizeAdLoading : appJSONGoogleMobileAdsOptimizeAdLoadingBool
102
109
  ]
110
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
103
111
  }
104
112
  lintOptions {
105
113
  disable 'GradleCompatible'
@@ -0,0 +1,21 @@
1
+ package io.invertase.googlemobileads
2
+
3
+ import com.facebook.react.bridge.WritableMap
4
+ import com.facebook.react.uimanager.events.Event
5
+
6
+ class OnNativeEvent(viewId: Int, private val event: WritableMap) : Event<OnNativeEvent>(viewId) {
7
+
8
+ override fun getEventName(): String {
9
+ return EVENT_NAME
10
+ }
11
+
12
+ override fun getCoalescingKey(): Short = 0
13
+
14
+ override fun getEventData(): WritableMap? {
15
+ return event
16
+ }
17
+
18
+ companion object {
19
+ const val EVENT_NAME = "topNative"
20
+ }
21
+ }
@@ -22,14 +22,14 @@ import androidx.annotation.NonNull;
22
22
  import com.facebook.react.bridge.Arguments;
23
23
  import com.facebook.react.bridge.ReactContext;
24
24
  import com.facebook.react.bridge.ReadableArray;
25
- import com.facebook.react.bridge.ReadableMap;
26
25
  import com.facebook.react.bridge.WritableMap;
27
26
  import com.facebook.react.common.MapBuilder;
28
27
  import com.facebook.react.uimanager.PixelUtil;
29
28
  import com.facebook.react.uimanager.SimpleViewManager;
30
29
  import com.facebook.react.uimanager.ThemedReactContext;
30
+ import com.facebook.react.uimanager.UIManagerHelper;
31
31
  import com.facebook.react.uimanager.annotations.ReactProp;
32
- import com.facebook.react.uimanager.events.RCTEventEmitter;
32
+ import com.facebook.react.uimanager.events.EventDispatcher;
33
33
  import com.facebook.react.views.view.ReactViewGroup;
34
34
  import com.google.android.gms.ads.AdListener;
35
35
  import com.google.android.gms.ads.AdRequest;
@@ -40,12 +40,15 @@ import com.google.android.gms.ads.LoadAdError;
40
40
  import com.google.android.gms.ads.admanager.AdManagerAdView;
41
41
  import com.google.android.gms.ads.admanager.AppEventListener;
42
42
  import io.invertase.googlemobileads.common.ReactNativeAdView;
43
+ import io.invertase.googlemobileads.common.SharedUtils;
43
44
  import java.util.ArrayList;
44
45
  import java.util.List;
45
46
  import java.util.Map;
46
47
  import java.util.Objects;
47
48
  import javax.annotation.Nonnull;
48
49
  import javax.annotation.Nullable;
50
+ import org.json.JSONException;
51
+ import org.json.JSONObject;
49
52
 
50
53
  public class ReactNativeGoogleMobileAdsBannerAdViewManager
51
54
  extends SimpleViewManager<ReactNativeAdView> {
@@ -73,7 +76,7 @@ public class ReactNativeGoogleMobileAdsBannerAdViewManager
73
76
  @Override
74
77
  public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
75
78
  MapBuilder.Builder<String, Object> builder = MapBuilder.builder();
76
- builder.put("onNativeEvent", MapBuilder.of("registrationName", "onNativeEvent"));
79
+ builder.put(OnNativeEvent.EVENT_NAME, MapBuilder.of("registrationName", "onNativeEvent"));
77
80
  return builder.build();
78
81
  }
79
82
 
@@ -104,9 +107,15 @@ public class ReactNativeGoogleMobileAdsBannerAdViewManager
104
107
  }
105
108
 
106
109
  @ReactProp(name = "request")
107
- public void setRequest(ReactNativeAdView reactViewGroup, ReadableMap value) {
108
- reactViewGroup.setRequest(ReactNativeGoogleMobileAdsCommon.buildAdRequest(value));
109
- reactViewGroup.setPropsChanged(true);
110
+ public void setRequest(ReactNativeAdView reactViewGroup, String value) {
111
+ try {
112
+ JSONObject jsonObject = new JSONObject(value);
113
+ WritableMap writableMap = SharedUtils.jsonObjectToWritableMap(jsonObject);
114
+ reactViewGroup.setRequest(ReactNativeGoogleMobileAdsCommon.buildAdRequest(writableMap));
115
+ reactViewGroup.setPropsChanged(true);
116
+ } catch (JSONException e) {
117
+ e.printStackTrace();
118
+ }
110
119
  }
111
120
 
112
121
  @ReactProp(name = "sizes")
@@ -274,8 +283,11 @@ public class ReactNativeGoogleMobileAdsBannerAdViewManager
274
283
  event.merge(payload);
275
284
  }
276
285
 
277
- ((ThemedReactContext) reactViewGroup.getContext())
278
- .getJSModule(RCTEventEmitter.class)
279
- .receiveEvent(reactViewGroup.getId(), "onNativeEvent", event);
286
+ ThemedReactContext themedReactContext = ((ThemedReactContext) reactViewGroup.getContext());
287
+ EventDispatcher eventDispatcher =
288
+ UIManagerHelper.getEventDispatcherForReactTag(themedReactContext, reactViewGroup.getId());
289
+ if (eventDispatcher != null) {
290
+ eventDispatcher.dispatchEvent(new OnNativeEvent(reactViewGroup.getId(), event));
291
+ }
280
292
  }
281
293
  }
@@ -25,6 +25,7 @@ import android.net.Uri;
25
25
  import android.os.Build;
26
26
  import android.util.Log;
27
27
  import com.facebook.react.bridge.*;
28
+ import com.facebook.react.bridge.WritableNativeMap;
28
29
  import com.facebook.react.common.LifecycleState;
29
30
  import com.facebook.react.modules.core.DeviceEventManagerModule;
30
31
  import java.io.File;
@@ -239,28 +240,29 @@ public class SharedUtils {
239
240
  }
240
241
 
241
242
  public static WritableMap jsonObjectToWritableMap(JSONObject jsonObject) throws JSONException {
242
- Iterator<String> iterator = jsonObject.keys();
243
- WritableMap writableMap = Arguments.createMap();
243
+ WritableMap map = new WritableNativeMap();
244
244
 
245
+ Iterator<String> iterator = jsonObject.keys();
245
246
  while (iterator.hasNext()) {
246
247
  String key = iterator.next();
247
248
  Object value = jsonObject.get(key);
248
- if (value instanceof Float || value instanceof Double) {
249
- writableMap.putDouble(key, jsonObject.getDouble(key));
250
- } else if (value instanceof Number) {
251
- writableMap.putInt(key, jsonObject.getInt(key));
252
- } else if (value instanceof String) {
253
- writableMap.putString(key, jsonObject.getString(key));
254
- } else if (value instanceof JSONObject) {
255
- writableMap.putMap(key, jsonObjectToWritableMap(jsonObject.getJSONObject(key)));
249
+ if (value instanceof JSONObject) {
250
+ map.putMap(key, jsonObjectToWritableMap((JSONObject) value));
256
251
  } else if (value instanceof JSONArray) {
257
- writableMap.putArray(key, jsonArrayToWritableArray(jsonObject.getJSONArray(key)));
258
- } else if (value == JSONObject.NULL) {
259
- writableMap.putNull(key);
252
+ map.putArray(key, jsonArrayToWritableArray((JSONArray) value));
253
+ } else if (value instanceof Boolean) {
254
+ map.putBoolean(key, (Boolean) value);
255
+ } else if (value instanceof Integer) {
256
+ map.putInt(key, (Integer) value);
257
+ } else if (value instanceof Double) {
258
+ map.putDouble(key, (Double) value);
259
+ } else if (value instanceof String) {
260
+ map.putString(key, (String) value);
261
+ } else {
262
+ map.putString(key, value.toString());
260
263
  }
261
264
  }
262
-
263
- return writableMap;
265
+ return map;
264
266
  }
265
267
 
266
268
  public static WritableArray jsonArrayToWritableArray(JSONArray jsonArray) throws JSONException {
@@ -15,6 +15,8 @@
15
15
  *
16
16
  */
17
17
 
18
+ #if !TARGET_OS_MACCATALYST
19
+
18
20
  #import <React/RCTBridgeModule.h>
19
21
 
20
22
  @interface RCT_EXTERN_MODULE (RNGoogleMobileAdsAppOpenModule, NSObject)
@@ -40,3 +42,5 @@ RCT_EXTERN_METHOD(appOpenShow
40
42
  : (RCTPromiseRejectBlock)reject)
41
43
 
42
44
  @end
45
+
46
+ #endif
@@ -15,6 +15,8 @@
15
15
  *
16
16
  */
17
17
 
18
+ #if !targetEnvironment(macCatalyst)
19
+
18
20
  import Foundation
19
21
  import GoogleMobileAds
20
22
 
@@ -79,3 +81,5 @@ class RNGoogleMobileAdsAppOpenModule: NSObject {
79
81
  }
80
82
  }
81
83
  }
84
+
85
+ #endif
@@ -15,6 +15,8 @@
15
15
  *
16
16
  */
17
17
 
18
+ #if !TARGET_OS_MACCATALYST
19
+
18
20
  #import <GoogleMobileAds/GADAppEventDelegate.h>
19
21
  #import <GoogleMobileAds/GADBannerView.h>
20
22
  #import <GoogleMobileAds/GADBannerViewDelegate.h>
@@ -37,3 +39,5 @@
37
39
  - (void)recordManualImpression;
38
40
 
39
41
  @end
42
+
43
+ #endif
@@ -15,6 +15,8 @@
15
15
  *
16
16
  */
17
17
 
18
+ #if !TARGET_OS_MACCATALYST
19
+
18
20
  #import "RNGoogleMobileAdsBannerComponent.h"
19
21
  #import <React/RCTLog.h>
20
22
  #import "RNGoogleMobileAdsCommon.h"
@@ -64,8 +66,13 @@
64
66
  _propsChanged = true;
65
67
  }
66
68
 
67
- - (void)setRequest:(NSDictionary *)request {
68
- _request = request;
69
+ - (void)setRequest:(NSString *)request {
70
+ NSData *jsonData = [request dataUsingEncoding:NSUTF8StringEncoding];
71
+ NSError *error = nil;
72
+ _request = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
73
+ if (error) {
74
+ NSLog(@"Error parsing JSON: %@", error.localizedDescription);
75
+ }
69
76
  _propsChanged = true;
70
77
  }
71
78
 
@@ -154,3 +161,5 @@
154
161
  }
155
162
 
156
163
  @end
164
+
165
+ #endif
@@ -0,0 +1,30 @@
1
+ // This guard prevent this file to be compiled in the old architecture.
2
+ #ifdef RCT_NEW_ARCH_ENABLED
3
+ #import <GoogleMobileAds/GADAppEventDelegate.h>
4
+ #import <GoogleMobileAds/GADBannerView.h>
5
+ #import <GoogleMobileAds/GADBannerViewDelegate.h>
6
+ #import <React/RCTViewComponentView.h>
7
+ #import <UIKit/UIKit.h>
8
+
9
+ #ifndef NativeComponentExampleComponentView_h
10
+ #define NativeComponentExampleComponentView_h
11
+
12
+ NS_ASSUME_NONNULL_BEGIN
13
+
14
+ @interface RNGoogleMobileAdsBannerView
15
+ : RCTViewComponentView <GADBannerViewDelegate, GADAppEventDelegate>
16
+
17
+ @property GADBannerView *banner;
18
+ @property(nonatomic, assign) BOOL requested;
19
+
20
+ @property(nonatomic, copy) NSArray *sizes;
21
+ @property(nonatomic, copy) NSString *unitId;
22
+ @property(nonatomic, copy) NSDictionary *request;
23
+ @property(nonatomic, copy) NSNumber *manualImpressionsEnabled;
24
+
25
+ @end
26
+
27
+ NS_ASSUME_NONNULL_END
28
+
29
+ #endif /* NativeComponentExampleComponentView_h */
30
+ #endif /* RCT_NEW_ARCH_ENABLED */
@@ -0,0 +1,220 @@
1
+ // This guard prevent the code from being compiled in the old architecture
2
+ #ifdef RCT_NEW_ARCH_ENABLED
3
+ #import "RNGoogleMobileAdsBannerView.h"
4
+ #import "RNGoogleMobileAdsCommon.h"
5
+
6
+ #import <react/renderer/components/RNGoogleMobileAdsSpec/ComponentDescriptors.h>
7
+ #import <react/renderer/components/RNGoogleMobileAdsSpec/EventEmitters.h>
8
+ #import <react/renderer/components/RNGoogleMobileAdsSpec/Props.h>
9
+ #import <react/renderer/components/RNGoogleMobileAdsSpec/RCTComponentViewHelpers.h>
10
+
11
+ #import "RCTFabricComponentsPlugins.h"
12
+
13
+ using namespace facebook::react;
14
+
15
+ @interface RNGoogleMobileAdsBannerView () <RCTRNGoogleMobileAdsBannerViewViewProtocol>
16
+
17
+ @end
18
+
19
+ @implementation RNGoogleMobileAdsBannerView
20
+
21
+ + (ComponentDescriptorProvider)componentDescriptorProvider {
22
+ return concreteComponentDescriptorProvider<RNGoogleMobileAdsBannerViewComponentDescriptor>();
23
+ }
24
+
25
+ - (instancetype)initWithFrame:(CGRect)frame {
26
+ if (self = [super initWithFrame:frame]) {
27
+ static const auto defaultProps = std::make_shared<const RNGoogleMobileAdsBannerViewProps>();
28
+ _props = defaultProps;
29
+ }
30
+
31
+ return self;
32
+ }
33
+
34
+ - (void)prepareForRecycle {
35
+ [super prepareForRecycle];
36
+ static const auto defaultProps = std::make_shared<const RNGoogleMobileAdsBannerViewProps>();
37
+ _props = defaultProps;
38
+ }
39
+
40
+ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps {
41
+ const auto &oldViewProps =
42
+ *std::static_pointer_cast<RNGoogleMobileAdsBannerViewProps const>(_props);
43
+ const auto &newViewProps =
44
+ *std::static_pointer_cast<RNGoogleMobileAdsBannerViewProps const>(props);
45
+
46
+ BOOL propsChanged = false;
47
+
48
+ if (oldViewProps.unitId != newViewProps.unitId) {
49
+ _unitId = [[NSString alloc] initWithUTF8String:newViewProps.unitId.c_str()];
50
+ propsChanged = true;
51
+ }
52
+
53
+ if (oldViewProps.sizes != newViewProps.sizes) {
54
+ NSMutableArray *adSizes = [NSMutableArray arrayWithCapacity:newViewProps.sizes.size()];
55
+ for (auto i = 0; i < newViewProps.sizes.size(); i++) {
56
+ NSString *jsonValue = [[NSString alloc] initWithUTF8String:newViewProps.sizes[i].c_str()];
57
+ GADAdSize adSize = [RNGoogleMobileAdsCommon stringToAdSize:jsonValue];
58
+ if (GADAdSizeEqualToSize(adSize, GADAdSizeInvalid)) {
59
+ RCTLogWarn(@"Invalid adSize %@", jsonValue);
60
+ } else {
61
+ [adSizes addObject:NSValueFromGADAdSize(adSize)];
62
+ }
63
+ }
64
+ _sizes = adSizes;
65
+ propsChanged = true;
66
+ }
67
+
68
+ if (_request == nil) {
69
+ _request = [NSDictionary dictionary];
70
+ }
71
+ if (oldViewProps.request != newViewProps.request) {
72
+ NSString *jsonString = [[NSString alloc] initWithUTF8String:newViewProps.request.c_str()];
73
+ NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
74
+ NSError *error = nil;
75
+ _request = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
76
+ if (error) {
77
+ NSLog(@"Error parsing JSON: %@", error.localizedDescription);
78
+ }
79
+ propsChanged = true;
80
+ }
81
+
82
+ if (_manualImpressionsEnabled == nil) {
83
+ _manualImpressionsEnabled = [NSNumber numberWithBool:oldViewProps.manualImpressionsEnabled];
84
+ }
85
+ if (oldViewProps.manualImpressionsEnabled != newViewProps.manualImpressionsEnabled) {
86
+ _manualImpressionsEnabled = [NSNumber numberWithBool:newViewProps.manualImpressionsEnabled];
87
+ propsChanged = true;
88
+ }
89
+
90
+ if (propsChanged) {
91
+ [self requestAd];
92
+ }
93
+
94
+ [super updateProps:props oldProps:oldProps];
95
+ }
96
+
97
+ #pragma mark - Methods
98
+
99
+ - (void)initBanner:(GADAdSize)adSize {
100
+ if (_requested) {
101
+ [_banner removeFromSuperview];
102
+ }
103
+ if ([RNGoogleMobileAdsCommon isAdManagerUnit:_unitId]) {
104
+ _banner = [[GAMBannerView alloc] initWithAdSize:adSize];
105
+
106
+ ((GAMBannerView *)_banner).validAdSizes = _sizes;
107
+ ((GAMBannerView *)_banner).appEventDelegate = self;
108
+ ((GAMBannerView *)_banner).enableManualImpressions = [_manualImpressionsEnabled boolValue];
109
+ } else {
110
+ _banner = [[GADBannerView alloc] initWithAdSize:adSize];
111
+ }
112
+ _banner.rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
113
+ _banner.delegate = self;
114
+ }
115
+
116
+ - (void)requestAd {
117
+ #ifndef __LP64__
118
+ return; // prevent crash on 32bit
119
+ #endif
120
+
121
+ if (_unitId == nil || _sizes == nil || _request == nil || _manualImpressionsEnabled == nil) {
122
+ [self setRequested:NO];
123
+ return;
124
+ } else {
125
+ [self initBanner:GADAdSizeFromNSValue(_sizes[0])];
126
+ [self addSubview:_banner];
127
+ _banner.adUnitID = _unitId;
128
+ [self setRequested:YES];
129
+ [_banner loadRequest:[RNGoogleMobileAdsCommon buildAdRequest:_request]];
130
+ if (_eventEmitter != nullptr) {
131
+ std::dynamic_pointer_cast<const facebook::react::RNGoogleMobileAdsBannerViewEventEmitter>(
132
+ _eventEmitter)
133
+ ->onNativeEvent(facebook::react::RNGoogleMobileAdsBannerViewEventEmitter::OnNativeEvent{
134
+ .type = "onSizeChange",
135
+ .width = _banner.bounds.size.width,
136
+ .height = _banner.bounds.size.height});
137
+ }
138
+ }
139
+ }
140
+
141
+ - (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args {
142
+ if ([commandName isEqual:@"recordManualImpression"]) {
143
+ [self recordManualImpression];
144
+ }
145
+ }
146
+
147
+ - (void)recordManualImpression {
148
+ if ([_banner class] == [GAMBannerView class]) {
149
+ [((GAMBannerView *)_banner) recordImpression];
150
+ }
151
+ }
152
+
153
+ #pragma mark - Events
154
+
155
+ - (void)bannerViewDidReceiveAd:(GADBannerView *)bannerView {
156
+ if (_eventEmitter != nullptr) {
157
+ std::dynamic_pointer_cast<const facebook::react::RNGoogleMobileAdsBannerViewEventEmitter>(
158
+ _eventEmitter)
159
+ ->onNativeEvent(facebook::react::RNGoogleMobileAdsBannerViewEventEmitter::OnNativeEvent{
160
+ .type = "onAdLoaded",
161
+ .width = bannerView.bounds.size.width,
162
+ .height = bannerView.bounds.size.height});
163
+ }
164
+ }
165
+
166
+ - (void)bannerView:(GADBannerView *)bannerView didFailToReceiveAdWithError:(NSError *)error {
167
+ NSDictionary *errorAndMessage = [RNGoogleMobileAdsCommon getCodeAndMessageFromAdError:error];
168
+ if (_eventEmitter != nullptr) {
169
+ std::dynamic_pointer_cast<const facebook::react::RNGoogleMobileAdsBannerViewEventEmitter>(
170
+ _eventEmitter)
171
+ ->onNativeEvent(facebook::react::RNGoogleMobileAdsBannerViewEventEmitter::OnNativeEvent{
172
+ .type = "onAdFailedToLoad",
173
+ .code = std::string([[errorAndMessage valueForKey:@"code"] UTF8String]),
174
+ .message = std::string([[errorAndMessage valueForKey:@"message"] UTF8String])});
175
+ }
176
+ }
177
+
178
+ - (void)bannerViewWillPresentScreen:(GADBannerView *)bannerView {
179
+ if (_eventEmitter != nullptr) {
180
+ std::dynamic_pointer_cast<const facebook::react::RNGoogleMobileAdsBannerViewEventEmitter>(
181
+ _eventEmitter)
182
+ ->onNativeEvent(facebook::react::RNGoogleMobileAdsBannerViewEventEmitter::OnNativeEvent{
183
+ .type = "onAdOpened"});
184
+ }
185
+ }
186
+
187
+ - (void)bannerViewWillDismissScreen:(GADBannerView *)bannerView {
188
+ // not in use
189
+ }
190
+
191
+ - (void)bannerViewDidDismissScreen:(GADBannerView *)bannerView {
192
+ if (_eventEmitter != nullptr) {
193
+ std::dynamic_pointer_cast<const facebook::react::RNGoogleMobileAdsBannerViewEventEmitter>(
194
+ _eventEmitter)
195
+ ->onNativeEvent(facebook::react::RNGoogleMobileAdsBannerViewEventEmitter::OnNativeEvent{
196
+ .type = "onAdClosed"});
197
+ }
198
+ }
199
+
200
+ - (void)adView:(nonnull GADBannerView *)banner
201
+ didReceiveAppEvent:(nonnull NSString *)name
202
+ withInfo:(nullable NSString *)info {
203
+ if (_eventEmitter != nullptr) {
204
+ std::dynamic_pointer_cast<const facebook::react::RNGoogleMobileAdsBannerViewEventEmitter>(
205
+ _eventEmitter)
206
+ ->onNativeEvent(facebook::react::RNGoogleMobileAdsBannerViewEventEmitter::OnNativeEvent{
207
+ .type = "onAppEvent",
208
+ .name = std::string([name UTF8String]),
209
+ .data = std::string([info UTF8String])});
210
+ }
211
+ }
212
+
213
+ #pragma mark - RNGoogleMobileAdsBannerViewCls
214
+
215
+ Class<RCTComponentViewProtocol> RNGoogleMobileAdsBannerViewCls(void) {
216
+ return RNGoogleMobileAdsBannerView.class;
217
+ }
218
+
219
+ @end
220
+ #endif