react-native-applovin-max 8.2.0 → 9.0.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 (151) hide show
  1. package/android/build.gradle +13 -2
  2. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXAdView.java +33 -26
  3. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXAdViewManagerImpl.java +110 -0
  4. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXAdViewUiComponent.java +15 -13
  5. package/android/src/main/java/com/applovin/reactnative/{AppLovinMAXModule.java → AppLovinMAXModuleImpl.java} +107 -168
  6. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXNativeAdView.java +84 -56
  7. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXNativeAdViewManagerImpl.java +101 -0
  8. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXPackage.java +44 -11
  9. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXUtils.java +56 -0
  10. package/android/src/newarch/com/applovin/reactnative/AppLovinMAXAdViewManager.java +151 -0
  11. package/android/src/newarch/com/applovin/reactnative/AppLovinMAXModule.java +453 -0
  12. package/android/src/newarch/com/applovin/reactnative/AppLovinMAXNativeAdViewManager.java +130 -0
  13. package/android/src/oldarch/com/applovin/reactnative/AppLovinMAXAdViewManager.java +128 -0
  14. package/android/src/oldarch/com/applovin/reactnative/AppLovinMAXModule.java +453 -0
  15. package/android/src/oldarch/com/applovin/reactnative/AppLovinMAXNativeAdViewManager.java +93 -0
  16. package/ios/AppLovinMAX.h +8 -3
  17. package/ios/{AppLovinMAX.m → AppLovinMAX.mm} +66 -53
  18. package/ios/AppLovinMAXAdView.h +7 -2
  19. package/ios/AppLovinMAXAdView.mm +747 -0
  20. package/ios/{AppLovinMAXAdViewManager.m → AppLovinMAXAdViewManager.mm} +3 -2
  21. package/ios/{AppLovinMAXAdViewUIComponent.m → AppLovinMAXAdViewUIComponent.mm} +2 -1
  22. package/ios/AppLovinMAXNativeAdView.h +15 -4
  23. package/ios/AppLovinMAXNativeAdView.mm +745 -0
  24. package/ios/AppLovinMAXNativeAdViewManager.mm +116 -0
  25. package/lib/commonjs/AdView.js +61 -85
  26. package/lib/commonjs/AdView.js.map +1 -1
  27. package/lib/commonjs/AppLovinMAX.js +11 -10
  28. package/lib/commonjs/AppLovinMAX.js.map +1 -1
  29. package/lib/commonjs/AppOpenAd.js +8 -10
  30. package/lib/commonjs/AppOpenAd.js.map +1 -1
  31. package/lib/commonjs/BannerAd.js +19 -21
  32. package/lib/commonjs/BannerAd.js.map +1 -1
  33. package/lib/commonjs/ErrorCode.js +3 -5
  34. package/lib/commonjs/ErrorCode.js.map +1 -1
  35. package/lib/commonjs/EventEmitter.js +3 -5
  36. package/lib/commonjs/EventEmitter.js.map +1 -1
  37. package/lib/commonjs/InterstitialAd.js +8 -10
  38. package/lib/commonjs/InterstitialAd.js.map +1 -1
  39. package/lib/commonjs/MRecAd.js +14 -16
  40. package/lib/commonjs/MRecAd.js.map +1 -1
  41. package/lib/commonjs/Privacy.js +3 -5
  42. package/lib/commonjs/Privacy.js.map +1 -1
  43. package/lib/commonjs/RewardedAd.js +8 -10
  44. package/lib/commonjs/RewardedAd.js.map +1 -1
  45. package/lib/commonjs/Utils.js +25 -0
  46. package/lib/commonjs/Utils.js.map +1 -0
  47. package/lib/commonjs/nativeAd/NativeAdView.js +65 -42
  48. package/lib/commonjs/nativeAd/NativeAdView.js.map +1 -1
  49. package/lib/commonjs/nativeAd/NativeAdViewComponents.js +51 -47
  50. package/lib/commonjs/nativeAd/NativeAdViewComponents.js.map +1 -1
  51. package/lib/commonjs/nativeAd/NativeAdViewProvider.js +38 -8
  52. package/lib/commonjs/nativeAd/NativeAdViewProvider.js.map +1 -1
  53. package/lib/commonjs/nativeAd/img/blank_icon.png +0 -0
  54. package/lib/commonjs/specs/AppLovinMAXAdViewNativeComponent.js +14 -0
  55. package/lib/commonjs/specs/AppLovinMAXAdViewNativeComponent.js.map +1 -0
  56. package/lib/commonjs/specs/AppLovinMAXNativeAdViewNativeComponent.js +14 -0
  57. package/lib/commonjs/specs/AppLovinMAXNativeAdViewNativeComponent.js.map +1 -0
  58. package/lib/commonjs/specs/NativeAppLovinMAXModule.js +9 -0
  59. package/lib/commonjs/specs/NativeAppLovinMAXModule.js.map +1 -0
  60. package/lib/module/AdView.js +56 -81
  61. package/lib/module/AdView.js.map +1 -1
  62. package/lib/module/AppLovinMAX.js +7 -7
  63. package/lib/module/AppLovinMAX.js.map +1 -1
  64. package/lib/module/AppOpenAd.js +1 -4
  65. package/lib/module/AppOpenAd.js.map +1 -1
  66. package/lib/module/BannerAd.js +1 -4
  67. package/lib/module/BannerAd.js.map +1 -1
  68. package/lib/module/ErrorCode.js +1 -4
  69. package/lib/module/ErrorCode.js.map +1 -1
  70. package/lib/module/EventEmitter.js +2 -4
  71. package/lib/module/EventEmitter.js.map +1 -1
  72. package/lib/module/InterstitialAd.js +2 -5
  73. package/lib/module/InterstitialAd.js.map +1 -1
  74. package/lib/module/MRecAd.js +1 -4
  75. package/lib/module/MRecAd.js.map +1 -1
  76. package/lib/module/Privacy.js +1 -4
  77. package/lib/module/Privacy.js.map +1 -1
  78. package/lib/module/RewardedAd.js +2 -5
  79. package/lib/module/RewardedAd.js.map +1 -1
  80. package/lib/module/Utils.js +17 -0
  81. package/lib/module/Utils.js.map +1 -0
  82. package/lib/module/nativeAd/NativeAdView.js +63 -40
  83. package/lib/module/nativeAd/NativeAdView.js.map +1 -1
  84. package/lib/module/nativeAd/NativeAdViewComponents.js +53 -49
  85. package/lib/module/nativeAd/NativeAdViewComponents.js.map +1 -1
  86. package/lib/module/nativeAd/NativeAdViewProvider.js +39 -9
  87. package/lib/module/nativeAd/NativeAdViewProvider.js.map +1 -1
  88. package/lib/module/nativeAd/img/blank_icon.png +0 -0
  89. package/lib/module/specs/AppLovinMAXAdViewNativeComponent.js +7 -0
  90. package/lib/module/specs/AppLovinMAXAdViewNativeComponent.js.map +1 -0
  91. package/lib/module/specs/AppLovinMAXNativeAdViewNativeComponent.js +7 -0
  92. package/lib/module/specs/AppLovinMAXNativeAdViewNativeComponent.js.map +1 -0
  93. package/lib/module/specs/NativeAppLovinMAXModule.js +3 -0
  94. package/lib/module/specs/NativeAppLovinMAXModule.js.map +1 -0
  95. package/lib/typescript/src/AdView.d.ts +11 -11
  96. package/lib/typescript/src/AdView.d.ts.map +1 -1
  97. package/lib/typescript/src/AppLovinMAX.d.ts.map +1 -1
  98. package/lib/typescript/src/AppOpenAd.d.ts.map +1 -1
  99. package/lib/typescript/src/BannerAd.d.ts.map +1 -1
  100. package/lib/typescript/src/ErrorCode.d.ts.map +1 -1
  101. package/lib/typescript/src/EventEmitter.d.ts.map +1 -1
  102. package/lib/typescript/src/InterstitialAd.d.ts.map +1 -1
  103. package/lib/typescript/src/MRecAd.d.ts.map +1 -1
  104. package/lib/typescript/src/Privacy.d.ts.map +1 -1
  105. package/lib/typescript/src/RewardedAd.d.ts.map +1 -1
  106. package/lib/typescript/src/Utils.d.ts +16 -0
  107. package/lib/typescript/src/Utils.d.ts.map +1 -0
  108. package/lib/typescript/src/nativeAd/NativeAdView.d.ts.map +1 -1
  109. package/lib/typescript/src/nativeAd/NativeAdViewComponents.d.ts.map +1 -1
  110. package/lib/typescript/src/nativeAd/NativeAdViewProvider.d.ts +14 -5
  111. package/lib/typescript/src/nativeAd/NativeAdViewProvider.d.ts.map +1 -1
  112. package/lib/typescript/src/specs/AppLovinMAXAdViewNativeComponent.d.ts +86 -0
  113. package/lib/typescript/src/specs/AppLovinMAXAdViewNativeComponent.d.ts.map +1 -0
  114. package/lib/typescript/src/specs/AppLovinMAXNativeAdViewNativeComponent.d.ts +80 -0
  115. package/lib/typescript/src/specs/AppLovinMAXNativeAdViewNativeComponent.d.ts.map +1 -0
  116. package/lib/typescript/src/specs/NativeAppLovinMAXModule.d.ts +132 -0
  117. package/lib/typescript/src/specs/NativeAppLovinMAXModule.d.ts.map +1 -0
  118. package/lib/typescript/src/types/AdInfo.d.ts +1 -1
  119. package/lib/typescript/src/types/AdInfo.d.ts.map +1 -1
  120. package/lib/typescript/src/types/AdProps.d.ts +2 -2
  121. package/lib/typescript/src/types/AdProps.d.ts.map +1 -1
  122. package/lib/typescript/src/types/NativeAd.d.ts +4 -0
  123. package/lib/typescript/src/types/NativeAd.d.ts.map +1 -1
  124. package/package.json +9 -1
  125. package/react-native-applovin-max.podspec +2 -2
  126. package/src/AdView.tsx +56 -121
  127. package/src/AppLovinMAX.ts +7 -8
  128. package/src/AppOpenAd.ts +1 -3
  129. package/src/BannerAd.ts +1 -3
  130. package/src/ErrorCode.ts +1 -3
  131. package/src/EventEmitter.ts +2 -3
  132. package/src/InterstitialAd.ts +2 -4
  133. package/src/MRecAd.ts +1 -3
  134. package/src/Privacy.ts +1 -3
  135. package/src/RewardedAd.ts +2 -4
  136. package/src/Utils.ts +26 -0
  137. package/src/nativeAd/NativeAdView.tsx +65 -65
  138. package/src/nativeAd/NativeAdViewComponents.tsx +32 -60
  139. package/src/nativeAd/NativeAdViewProvider.tsx +37 -12
  140. package/src/nativeAd/img/blank_icon.png +0 -0
  141. package/src/specs/AppLovinMAXAdViewNativeComponent.ts +96 -0
  142. package/src/specs/AppLovinMAXNativeAdViewNativeComponent.ts +89 -0
  143. package/src/specs/NativeAppLovinMAXModule.ts +208 -0
  144. package/src/types/AdInfo.ts +1 -1
  145. package/src/types/AdProps.ts +2 -2
  146. package/src/types/NativeAd.ts +5 -0
  147. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXAdViewManager.java +0 -149
  148. package/android/src/main/java/com/applovin/reactnative/AppLovinMAXNativeAdViewManager.java +0 -163
  149. package/ios/AppLovinMAXAdView.m +0 -325
  150. package/ios/AppLovinMAXNativeAdView.m +0 -432
  151. package/ios/AppLovinMAXNativeAdViewManager.m +0 -64
@@ -0,0 +1,745 @@
1
+ //
2
+ // AppLovinMAXNativeAdView.m
3
+ // AppLovin MAX React Native Module
4
+ //
5
+ // Copyright © 2022 AppLovin. All rights reserved.
6
+ //
7
+
8
+ #import <React/RCTUIManagerUtils.h>
9
+ #import <React/RCTImageView.h>
10
+ #import <AppLovinSDK/AppLovinSDK.h>
11
+ #import "AppLovinMAX.h"
12
+ #import "AppLovinMAXNativeAdView.h"
13
+
14
+ #ifdef RCT_NEW_ARCH_ENABLED
15
+
16
+ #import <react/renderer/components/RNAppLovinMAXSpec/ComponentDescriptors.h>
17
+ #import <react/renderer/components/RNAppLovinMAXSpec/EventEmitters.h>
18
+ #import <react/renderer/components/RNAppLovinMAXSpec/Props.h>
19
+ #import <react/renderer/components/RNAppLovinMAXSpec/RCTComponentViewHelpers.h>
20
+ #import <React/RCTConversions.h>
21
+ #import "RCTFabricComponentsPlugins.h"
22
+
23
+ @interface RCTBridge (Private)
24
+ + (RCTBridge *)currentBridge;
25
+ @end
26
+
27
+ using namespace facebook::react;
28
+
29
+ #endif
30
+
31
+ #define TITLE_LABEL_TAG 1
32
+ #define MEDIA_VIEW_CONTAINER_TAG 2
33
+ #define ICON_VIEW_TAG 3
34
+ #define BODY_VIEW_TAG 4
35
+ #define CALL_TO_ACTION_VIEW_TAG 5
36
+ #define ADVERTISER_VIEW_TAG 8
37
+
38
+ @interface MANativeAdLoader()
39
+ - (void)registerClickableViews:(NSArray<UIView *> *)clickableViews
40
+ withContainer:(UIView *)container
41
+ forAd:(MAAd *)ad;
42
+ - (void)handleNativeAdViewRenderedForAd:(MAAd *)ad;
43
+ @end
44
+
45
+ #ifdef RCT_NEW_ARCH_ENABLED
46
+ @interface AppLovinMAXNativeAdView()<RCTAppLovinMAXNativeAdViewViewProtocol, MANativeAdDelegate, MAAdRevenueDelegate>
47
+ #else
48
+ @interface AppLovinMAXNativeAdView()<MANativeAdDelegate, MAAdRevenueDelegate>
49
+ #endif
50
+
51
+ @property (nonatomic, weak) RCTBridge *bridge;
52
+ @property (nonatomic, strong, nullable) MANativeAdLoader *adLoader;
53
+ @property (nonatomic, strong, nullable) MAAd *nativeAd;
54
+ @property (nonatomic, strong) ALAtomicBoolean *isLoading; // Guard against repeated ad loads
55
+ @property (nonatomic, strong) ALAtomicBoolean *isAdUnitIdSet;
56
+
57
+ // JavaScript properties
58
+ @property (nonatomic, copy) NSString *adUnitId;
59
+ @property (nonatomic, copy, nullable) NSString *placement;
60
+ @property (nonatomic, copy, nullable) NSString *customData;
61
+ @property (nonatomic, copy, nullable) NSArray<NSDictionary<NSString *, id> *> *extraParameters;
62
+ @property (nonatomic, copy, nullable) NSArray<NSDictionary<NSString *, id> *> *localExtraParameters;
63
+
64
+ // Callback to `AppLovinNativeAdView.js`
65
+ @property (nonatomic, copy) RCTDirectEventBlock onAdLoadedEvent;
66
+ @property (nonatomic, copy) RCTDirectEventBlock onAdLoadFailedEvent;
67
+ @property (nonatomic, copy) RCTDirectEventBlock onAdClickedEvent;
68
+ @property (nonatomic, copy) RCTDirectEventBlock onAdRevenuePaidEvent;
69
+
70
+ // TODO: Allow publisher to select which views are clickable and which isn't via prop
71
+ @property (nonatomic, strong) NSMutableArray<UIView *> *clickableViews;
72
+
73
+ @end
74
+
75
+ @implementation AppLovinMAXNativeAdView
76
+
77
+ #ifdef RCT_NEW_ARCH_ENABLED
78
+
79
+ + (ComponentDescriptorProvider)componentDescriptorProvider
80
+ {
81
+ return concreteComponentDescriptorProvider<AppLovinMAXNativeAdViewComponentDescriptor>();
82
+ }
83
+
84
+ - (instancetype)initWithFrame:(CGRect)frame
85
+ {
86
+ self = [super initWithFrame: frame];
87
+ if ( self )
88
+ {
89
+ static const auto defaultProps = std::make_shared<const AppLovinMAXNativeAdViewProps>();
90
+ _props = defaultProps;
91
+
92
+ self.bridge = [RCTBridge currentBridge];
93
+ self.isLoading = [[ALAtomicBoolean alloc] init];
94
+ self.isAdUnitIdSet = [[ALAtomicBoolean alloc] init];
95
+ self.clickableViews = [NSMutableArray array];
96
+
97
+ [self setupEventHandlers];
98
+ }
99
+ return self;
100
+ }
101
+
102
+ - (void)setupEventHandlers
103
+ {
104
+ self.onAdLoadedEvent = [self](NSDictionary *event)
105
+ {
106
+ if ( _eventEmitter )
107
+ {
108
+ auto nativeAdViewEventEmitter = std::static_pointer_cast<AppLovinMAXNativeAdViewEventEmitter const>(_eventEmitter);
109
+
110
+ NSDictionary *nativeAd = event[@"nativeAd"];
111
+ NSDictionary *nativeAdImpl = event[@"nativeAdImpl"];
112
+
113
+ AppLovinMAXNativeAdViewEventEmitter::OnAdLoadedEvent result =
114
+ {
115
+ .adUnitId = std::string([event[@"adUnitId"] ?: @"" UTF8String]),
116
+ .adFormat = std::string([event[@"adFormat"] ?: @"" UTF8String]),
117
+ .networkName = std::string([event[@"networkName"] ?: @"" UTF8String]),
118
+ .networkPlacement = std::string([event[@"networkPlacement"] ?: @"" UTF8String]),
119
+ .creativeId = std::string([event[@"creativeId"] ?: @"" UTF8String]),
120
+ .placement = std::string([event[@"placement"] ?: @"" UTF8String]),
121
+ .revenue = [event[@"revenue"] doubleValue],
122
+ .revenuePrecision = std::string([event[@"revenuePrecision"] ?: @"" UTF8String]),
123
+ .latencyMillis = [event[@"latencyMillis"] doubleValue],
124
+ .dspName = std::string([event[@"dspName"] ?: @"" UTF8String]),
125
+ .size = {
126
+ .width = [event[@"size"][@"width"] doubleValue],
127
+ .height = [event[@"size"][@"height"] doubleValue],
128
+ },
129
+ .nativeAd = {
130
+ .title = std::string([nativeAd[@"title"] ?: @"" UTF8String]),
131
+ .advertiser = std::string([nativeAd[@"advertiser"] ?: @"" UTF8String]),
132
+ .body = std::string([nativeAd[@"body"] ?: @"" UTF8String]),
133
+ .callToAction = std::string([nativeAd[@"callToAction"] ?: @"" UTF8String]),
134
+ .starRating = [nativeAd[@"starRating"] doubleValue],
135
+ .mediaContentAspectRatio = [nativeAd[@"mediaContentAspectRatio"] doubleValue],
136
+ .isIconImageAvailable = [nativeAd[@"isIconImageAvailable"] boolValue],
137
+ .isOptionsViewAvailable = [nativeAd[@"isOptionsViewAvailable"] boolValue],
138
+ .isMediaViewAvailable = [nativeAd[@"isMediaViewAvailable"] boolValue],
139
+ },
140
+ .nativeAdImpl = {
141
+ .title = std::string([nativeAdImpl[@"title"] ?: @"" UTF8String]),
142
+ .advertiser = std::string([nativeAdImpl[@"advertiser"] ?: @"" UTF8String]),
143
+ .body = std::string([nativeAdImpl[@"body"] ?: @"" UTF8String]),
144
+ .callToAction = std::string([nativeAdImpl[@"callToAction"] ?: @"" UTF8String]),
145
+ .image = [nativeAdImpl[@"image"] boolValue],
146
+ .imageSource = std::string([nativeAdImpl[@"imageSource"] ?: @"" UTF8String]),
147
+ .url = std::string([nativeAdImpl[@"url"] ?: @"" UTF8String]),
148
+ .starRating = [nativeAdImpl[@"starRating"] doubleValue],
149
+ .isOptionsViewAvailable = [nativeAdImpl[@"isOptionsViewAvailable"] boolValue],
150
+ .isMediaViewAvailable = [nativeAdImpl[@"isMediaViewAvailable"] boolValue],
151
+ }
152
+ };
153
+
154
+ nativeAdViewEventEmitter->onAdLoadedEvent(result);
155
+ }
156
+ };
157
+
158
+ self.onAdLoadFailedEvent = [self](NSDictionary *event)
159
+ {
160
+ if ( _eventEmitter )
161
+ {
162
+ auto nativeAdViewEventEmitter = std::static_pointer_cast<AppLovinMAXNativeAdViewEventEmitter const>(_eventEmitter);
163
+
164
+ AppLovinMAXNativeAdViewEventEmitter::OnAdLoadFailedEvent result =
165
+ {
166
+ .adUnitId = std::string([event[@"adUnitId"] ?: @"" UTF8String]),
167
+ .code = [event[@"code"] doubleValue],
168
+ .message = std::string([event[@"message"] ?: @"" UTF8String]),
169
+ .mediatedNetworkErrorCode = [event[@"mediatedNetworkErrorCode"] doubleValue],
170
+ .mediatedNetworkErrorMessage = std::string([event[@"mediatedNetworkErrorMessage"] ?: @"" UTF8String]),
171
+ .adLoadFailureInfo = std::string([event[@"adLoadFailureInfo"] ?: @"" UTF8String])
172
+ };
173
+
174
+ nativeAdViewEventEmitter->onAdLoadFailedEvent(result);
175
+ }
176
+ };
177
+
178
+ self.onAdClickedEvent = [self](NSDictionary *event)
179
+ {
180
+ if ( _eventEmitter )
181
+ {
182
+ auto nativeAdViewEventEmitter = std::static_pointer_cast<AppLovinMAXNativeAdViewEventEmitter const>(_eventEmitter);
183
+
184
+ AppLovinMAXNativeAdViewEventEmitter::OnAdClickedEvent result =
185
+ {
186
+ .adUnitId = std::string([event[@"adUnitId"] ?: @"" UTF8String]),
187
+ .adFormat = std::string([event[@"adFormat"] ?: @"" UTF8String]),
188
+ .networkName = std::string([event[@"networkName"] ?: @"" UTF8String]),
189
+ .networkPlacement = std::string([event[@"networkPlacement"] ?: @"" UTF8String]),
190
+ .creativeId = std::string([event[@"creativeId"] ?: @"" UTF8String]),
191
+ .placement = std::string([event[@"placement"] ?: @"" UTF8String]),
192
+ .revenue = [event[@"revenue"] doubleValue],
193
+ .revenuePrecision = std::string([event[@"revenuePrecision"] ?: @"" UTF8String]),
194
+ .latencyMillis = [event[@"latencyMillis"] doubleValue],
195
+ .dspName = std::string([event[@"dspName"] ?: @"" UTF8String]),
196
+ .size = {
197
+ .width = [event[@"size"][@"width"] doubleValue],
198
+ .height = [event[@"size"][@"height"] doubleValue],
199
+ },
200
+ };
201
+
202
+ nativeAdViewEventEmitter->onAdClickedEvent(result);
203
+ }
204
+ };
205
+
206
+ self.onAdRevenuePaidEvent = [self](NSDictionary *event)
207
+ {
208
+ if ( _eventEmitter )
209
+ {
210
+ auto nativeAdViewEventEmitter = std::static_pointer_cast<AppLovinMAXNativeAdViewEventEmitter const>(_eventEmitter);
211
+
212
+ AppLovinMAXNativeAdViewEventEmitter::OnAdRevenuePaidEvent result =
213
+ {
214
+ .adUnitId = std::string([event[@"adUnitId"] ?: @"" UTF8String]),
215
+ .adFormat = std::string([event[@"adFormat"] ?: @"" UTF8String]),
216
+ .networkName = std::string([event[@"networkName"] ?: @"" UTF8String]),
217
+ .networkPlacement = std::string([event[@"networkPlacement"] ?: @"" UTF8String]),
218
+ .creativeId = std::string([event[@"creativeId"] ?: @"" UTF8String]),
219
+ .placement = std::string([event[@"placement"] ?: @"" UTF8String]),
220
+ .revenue = [event[@"revenue"] doubleValue],
221
+ .revenuePrecision = std::string([event[@"revenuePrecision"] ?: @"" UTF8String]),
222
+ .latencyMillis = [event[@"latencyMillis"] doubleValue],
223
+ .dspName = std::string([event[@"dspName"] ?: @"" UTF8String]),
224
+ .size = {
225
+ .width = [event[@"size"][@"width"] doubleValue],
226
+ .height = [event[@"size"][@"height"] doubleValue],
227
+ },
228
+ };
229
+
230
+ nativeAdViewEventEmitter->onAdRevenuePaidEvent(result);
231
+ }
232
+ };
233
+ }
234
+
235
+ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
236
+ {
237
+ const auto &oldViewProps = *std::static_pointer_cast<AppLovinMAXNativeAdViewProps const>(_props);
238
+ const auto &newViewProps = *std::static_pointer_cast<AppLovinMAXNativeAdViewProps const>(props);
239
+
240
+ if ( oldViewProps.adUnitId != newViewProps.adUnitId )
241
+ {
242
+ [self setAdUnitId: RCTNSStringFromString(newViewProps.adUnitId)];
243
+ }
244
+
245
+ if ( oldViewProps.placement != newViewProps.placement )
246
+ {
247
+ [self setPlacement: RCTNSStringFromStringNilIfEmpty(newViewProps.placement)];
248
+ }
249
+
250
+ if ( oldViewProps.customData != newViewProps.customData )
251
+ {
252
+ [self setCustomData: RCTNSStringFromStringNilIfEmpty(newViewProps.customData)];
253
+ }
254
+
255
+ if ( newViewProps.extraParameters.size() > 0 )
256
+ {
257
+ NSMutableArray *extraParameters = [NSMutableArray array];
258
+
259
+ for ( const auto &parameter: newViewProps.extraParameters )
260
+ {
261
+ NSDictionary *dict = @{@"key": RCTNSStringFromString(parameter.key),
262
+ @"value": RCTNSStringFromString(parameter.value)};
263
+ [extraParameters addObject: dict];
264
+ }
265
+
266
+ _extraParameters = extraParameters;
267
+ }
268
+
269
+ if ( newViewProps.strLocalExtraParameters.size() > 0 )
270
+ {
271
+ NSMutableArray *strLocalExtraParameters = [NSMutableArray array];
272
+
273
+ for ( const auto &parameter: newViewProps.strLocalExtraParameters )
274
+ {
275
+ NSDictionary *dict = @{@"key": RCTNSStringFromString(parameter.key),
276
+ @"value": RCTNSStringFromString(parameter.value)};
277
+ [strLocalExtraParameters addObject: dict];
278
+ }
279
+
280
+ [self setStrLocalExtraParameters: strLocalExtraParameters];
281
+ }
282
+
283
+ if ( newViewProps.boolLocalExtraParameters.size() > 0 )
284
+ {
285
+ NSMutableArray *boolLocalExtraParameters = [NSMutableArray array];
286
+
287
+ for ( const auto &parameter: newViewProps.boolLocalExtraParameters )
288
+ {
289
+ NSDictionary *dict = @{@"key": RCTNSStringFromString(parameter.key),
290
+ @"value": @(parameter.value)};
291
+ [boolLocalExtraParameters addObject: dict];
292
+ }
293
+
294
+ [self setBoolLocalExtraParameters: boolLocalExtraParameters];
295
+ }
296
+
297
+ if ( [self.isAdUnitIdSet compareAndSet: YES update: NO] )
298
+ {
299
+ [self loadAd];
300
+ }
301
+
302
+ [super updateProps: props oldProps: oldProps];
303
+ }
304
+
305
+ - (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args
306
+ {
307
+ if ( [commandName isEqualToString: @"loadAd"] )
308
+ {
309
+ [self loadAd];
310
+ }
311
+ else if ( [commandName isEqualToString: @"updateAssetView"] )
312
+ {
313
+ NSNumber *assetViewTag = (NSNumber *) args[0];
314
+ NSString *assetViewName = (NSString *) args[1];
315
+ [self updateAssetView: assetViewTag.doubleValue assetViewName: assetViewName];
316
+ }
317
+ else if ( [commandName isEqualToString: @"renderNativeAd"] )
318
+ {
319
+ [self renderNativeAd];
320
+ }
321
+ }
322
+
323
+ - (void)prepareForRecycle
324
+ {
325
+ [super prepareForRecycle];
326
+
327
+ static const auto defaultProps = std::make_shared<const AppLovinMAXNativeAdViewProps>();
328
+ _props = defaultProps;
329
+
330
+ [self destroyCurrentAdIfNeeded];
331
+ }
332
+
333
+ #endif // RCT_NEW_ARCH_ENABLED
334
+
335
+ - (instancetype)initWithBridge:(RCTBridge *)bridge
336
+ {
337
+ self = [super init];
338
+ if ( self )
339
+ {
340
+ self.bridge = bridge;
341
+ self.isLoading = [[ALAtomicBoolean alloc] init];
342
+ self.isAdUnitIdSet = [[ALAtomicBoolean alloc] init];
343
+ self.clickableViews = [NSMutableArray array];
344
+ }
345
+ return self;
346
+ }
347
+
348
+ // Lazily loaded for when Ad Unit ID is available
349
+ - (nullable MANativeAdLoader *)adLoader
350
+ {
351
+ if ( ![self.adUnitId al_isValidString] ) return nil;
352
+
353
+ if ( ![self.adUnitId isEqualToString: _adLoader.adUnitIdentifier] )
354
+ {
355
+ _adLoader = [[MANativeAdLoader alloc] initWithAdUnitIdentifier: self.adUnitId sdk: [AppLovinMAX shared].sdk];
356
+ _adLoader.nativeAdDelegate = self;
357
+ _adLoader.revenueDelegate = self;
358
+ }
359
+
360
+ return _adLoader;
361
+ }
362
+
363
+ - (void)didMoveToWindow
364
+ {
365
+ [super didMoveToWindow];
366
+
367
+ if ( !self.window )
368
+ {
369
+ [self destroyCurrentAdIfNeeded];
370
+ }
371
+ }
372
+
373
+ - (void)setAdUnitId:(NSString *)adUnitId
374
+ {
375
+ if ( ![adUnitId al_isValidString] ) return;
376
+
377
+ _adUnitId = adUnitId;
378
+
379
+ [self.isAdUnitIdSet set: YES];
380
+ }
381
+
382
+ - (void)setStrLocalExtraParameters:(NSArray<NSDictionary *> *)strLocalExtraParameters
383
+ {
384
+ if (!self.localExtraParameters)
385
+ {
386
+ self.localExtraParameters = [strLocalExtraParameters copy];
387
+ }
388
+ else
389
+ {
390
+ self.localExtraParameters = [self.localExtraParameters arrayByAddingObjectsFromArray: strLocalExtraParameters];
391
+ }
392
+ }
393
+
394
+ - (void)setBoolLocalExtraParameters:(NSArray<NSDictionary *> *)boolLocalExtraParameters
395
+ {
396
+ if (!self.localExtraParameters)
397
+ {
398
+ self.localExtraParameters = [boolLocalExtraParameters copy];
399
+ }
400
+ else
401
+ {
402
+ self.localExtraParameters = [self.localExtraParameters arrayByAddingObjectsFromArray: boolLocalExtraParameters];
403
+ }
404
+ }
405
+
406
+ // Called when Ad Unit ID is set, and via RN layer
407
+ - (void)loadAd
408
+ {
409
+ if ( ![AppLovinMAX shared].sdk )
410
+ {
411
+ [[AppLovinMAX shared] logUninitializedAccessError: @"AppLovinMAXNativeAdView.loadAd"];
412
+ return;
413
+ }
414
+
415
+ if ( [self.isLoading compareAndSet: NO update: YES] )
416
+ {
417
+ [[AppLovinMAX shared] log: @"Loading a native ad for Ad Unit ID: %@...", self.adUnitId];
418
+
419
+ self.adLoader.placement = self.placement;
420
+ self.adLoader.customData = self.customData;
421
+
422
+ for ( NSDictionary *parameter in self.extraParameters )
423
+ {
424
+ NSString *key = parameter[@"key"];
425
+ id value = parameter[@"value"];
426
+ [self.adLoader setExtraParameterForKey: key value: (value != [NSNull null] ? value : nil)];
427
+ }
428
+
429
+ for ( NSDictionary *parameter in self.localExtraParameters )
430
+ {
431
+ NSString *key = parameter[@"key"];
432
+ id value = parameter[@"value"];
433
+ [self.adLoader setLocalExtraParameterForKey: key value: (value != [NSNull null] ? value : nil)];
434
+ }
435
+
436
+ [self.adLoader loadAd];
437
+ }
438
+ else
439
+ {
440
+ [[AppLovinMAX shared] log: @"Ignoring request to load native ad for Ad Unit ID %@, another ad load in progress", self.adUnitId];
441
+ }
442
+ }
443
+
444
+ #pragma mark - Views to Replace
445
+
446
+ - (void)updateAssetView:(double)assetViewTag assetViewName:(NSString *)assetViewName
447
+ {
448
+ if ( [assetViewName isEqualToString: @"TitleView"] )
449
+ {
450
+ [self setTitleView: @(assetViewTag)];
451
+ }
452
+ else if ( [assetViewName isEqualToString: @"AdvertiserView"] )
453
+ {
454
+ [self setAdvertiserView: @(assetViewTag)];
455
+ }
456
+ else if ( [assetViewName isEqualToString: @"BodyView"] )
457
+ {
458
+ [self setBodyView: @(assetViewTag)];
459
+ }
460
+ else if ( [assetViewName isEqualToString: @"CallToActionView"] )
461
+ {
462
+ [self setCallToActionView: @(assetViewTag)];
463
+ }
464
+ else if ( [assetViewName isEqualToString: @"IconView"] )
465
+ {
466
+ [self setIconView: @(assetViewTag)];
467
+ }
468
+ else if ( [assetViewName isEqualToString: @"OptionsView"] )
469
+ {
470
+ [self setOptionsView: @(assetViewTag)];
471
+ }
472
+ else if ( [assetViewName isEqualToString: @"MediaView"] )
473
+ {
474
+ [self setMediaView: @(assetViewTag)];
475
+ }
476
+ }
477
+
478
+ - (void)setTitleView:(NSNumber *)tag
479
+ {
480
+ if ( !self.nativeAd.nativeAd.title ) return;
481
+
482
+ UIView *view = [self.bridge.uiManager viewForReactTag: tag];
483
+ if ( !view )
484
+ {
485
+ [[AppLovinMAX shared] log: @"Cannot find a title view with tag \"%@\" for %@", tag, self.adUnitId];
486
+ return;
487
+ }
488
+
489
+ view.tag = TITLE_LABEL_TAG;
490
+
491
+ [self.clickableViews addObject: view];
492
+ }
493
+
494
+ - (void)setAdvertiserView:(NSNumber *)tag
495
+ {
496
+ if ( !self.nativeAd.nativeAd.advertiser ) return;
497
+
498
+ UIView *view = [self.bridge.uiManager viewForReactTag: tag];
499
+ if ( !view )
500
+ {
501
+ [[AppLovinMAX shared] log: @"Cannot find an advertiser view with tag \"%@\" for %@", tag, self.adUnitId];
502
+ return;
503
+ }
504
+
505
+ view.tag = ADVERTISER_VIEW_TAG;
506
+
507
+ [self.clickableViews addObject: view];
508
+ }
509
+
510
+ - (void)setBodyView:(NSNumber *)tag
511
+ {
512
+ if ( !self.nativeAd.nativeAd.body ) return;
513
+
514
+ UIView *view = [self.bridge.uiManager viewForReactTag: tag];
515
+ if ( !view )
516
+ {
517
+ [[AppLovinMAX shared] log: @"Cannot find a body view with tag \"%@\" for %@", tag, self.adUnitId];
518
+ return;
519
+ }
520
+
521
+ view.tag = BODY_VIEW_TAG;
522
+
523
+ [self.clickableViews addObject: view];
524
+ }
525
+
526
+ - (void)setCallToActionView:(NSNumber *)tag
527
+ {
528
+ if ( !self.nativeAd.nativeAd.callToAction ) return;
529
+
530
+ UIView *view = [self.bridge.uiManager viewForReactTag: tag];
531
+ if ( !view )
532
+ {
533
+ [[AppLovinMAX shared] log: @"Cannot find a callToAction view with tag \"%@\" for %@", tag, self.adUnitId];
534
+ return;
535
+ }
536
+
537
+ view.tag = CALL_TO_ACTION_VIEW_TAG;
538
+
539
+ [self.clickableViews addObject: view];
540
+ }
541
+
542
+ - (void)setIconView:(NSNumber *)tag
543
+ {
544
+ UIView *view = [self.bridge.uiManager viewForReactTag: tag];
545
+ if ( !view )
546
+ {
547
+ [[AppLovinMAX shared] log: @"Cannot find an icon image view with tag \"%@\" for %@", tag, self.adUnitId];
548
+ return;
549
+ }
550
+
551
+ view.tag = ICON_VIEW_TAG;
552
+
553
+ [self.clickableViews addObject: view];
554
+ }
555
+
556
+ - (void)setOptionsView:(NSNumber *)tag
557
+ {
558
+ if ( !self.nativeAd.nativeAd.optionsView ) return;
559
+
560
+ UIView *view = [self.bridge.uiManager viewForReactTag: tag];
561
+ if ( !view )
562
+ {
563
+ [[AppLovinMAX shared] log: @"Cannot find an option view with tag \"%@\" for %@", tag, self.adUnitId];
564
+ return;
565
+ }
566
+
567
+ [view addSubview: self.nativeAd.nativeAd.optionsView];
568
+ [self.nativeAd.nativeAd.optionsView al_pinToSuperview];
569
+ }
570
+
571
+ - (void)setMediaView:(NSNumber *)tag
572
+ {
573
+ if ( !self.nativeAd.nativeAd.mediaView ) return;
574
+
575
+ UIView *view = [self.bridge.uiManager viewForReactTag: tag];
576
+ if ( !view )
577
+ {
578
+ [[AppLovinMAX shared] log: @"Cannot find a media view with tag \"%@\" for %@", tag, self.adUnitId];
579
+ return;
580
+ }
581
+
582
+ view.tag = MEDIA_VIEW_CONTAINER_TAG;
583
+
584
+ [self.clickableViews addObject: view];
585
+
586
+ [view addSubview: self.nativeAd.nativeAd.mediaView];
587
+ [self.nativeAd.nativeAd.mediaView al_pinToSuperview];
588
+ }
589
+
590
+ - (void)renderNativeAd
591
+ {
592
+ if ( !self.adLoader ) return;
593
+
594
+ [self.adLoader registerClickableViews: self.clickableViews withContainer: self forAd: self.nativeAd];
595
+ [self.adLoader handleNativeAdViewRenderedForAd: self.nativeAd];
596
+ }
597
+
598
+ /**
599
+ * Invoked:
600
+ * 1. after all the JavaScript properties are set when mounting NativeAdView
601
+ * 2. after all the user's asset views are mounted, following the 1st event
602
+ */
603
+ - (void)didSetProps:(NSArray<NSString *> *)changedProps
604
+ {
605
+ if ( [self.isAdUnitIdSet compareAndSet:YES update: NO] )
606
+ {
607
+ [self loadAd];
608
+ }
609
+ }
610
+
611
+ #pragma mark - Ad Loader Delegate
612
+
613
+ - (void)didLoadNativeAd:(nullable MANativeAdView *)nativeAdView forAd:(MAAd *)ad
614
+ {
615
+ [[AppLovinMAX shared] log: @"Native ad loaded: %@", ad];
616
+
617
+ // Log a warning if it is a template native ad returned - as our plugin will be responsible for re-rendering the native ad's assets
618
+ if ( nativeAdView )
619
+ {
620
+ [self.isLoading set: NO];
621
+
622
+ [[AppLovinMAX shared] log: @"Native ad is of template type, failing ad load..."];
623
+ self.onAdLoadFailedEvent([[AppLovinMAX shared] adLoadFailedInfoForAd: self.adUnitId withError: nil]);
624
+
625
+ return;
626
+ }
627
+
628
+ [self destroyCurrentAdIfNeeded];
629
+
630
+ self.nativeAd = ad;
631
+
632
+ // Notify `AppLovinNativeAdView.js`
633
+ [self sendAdLoadedReactNativeEventForAd: ad.nativeAd];
634
+
635
+ [self.isLoading set: NO];
636
+ }
637
+
638
+ - (void)sendAdLoadedReactNativeEventForAd:(MANativeAd *)ad
639
+ {
640
+ // 1. AdInfo for publisher to be notified via `onAdLoaded`
641
+
642
+ NSMutableDictionary<NSString *, id> *nativeAdInfo = [NSMutableDictionary dictionaryWithCapacity: 5];
643
+ nativeAdInfo[@"title"] = ad.title;
644
+ nativeAdInfo[@"advertiser"] = ad.advertiser;
645
+ nativeAdInfo[@"body"] = ad.body;
646
+ nativeAdInfo[@"callToAction"] = ad.callToAction;
647
+ nativeAdInfo[@"starRating"] = ad.starRating;
648
+
649
+ // The aspect ratio can be 0.0f when it is not provided by the network.
650
+ if ( ad.mediaContentAspectRatio > 0 )
651
+ {
652
+ nativeAdInfo[@"mediaContentAspectRatio"] = @(ad.mediaContentAspectRatio);
653
+ }
654
+
655
+ nativeAdInfo[@"isIconImageAvailable"] = @(ad.icon != nil || ad.iconView != nil);
656
+ nativeAdInfo[@"isOptionsViewAvailable"] = @(ad.optionsView != nil);
657
+ nativeAdInfo[@"isMediaViewAvailable"] = @(ad.mediaView != nil);
658
+
659
+ // 2. NativeAd for `AppLovinNativeAdView.js` to render the views
660
+
661
+ NSMutableDictionary<NSString *, id> *jsNativeAd = [NSMutableDictionary dictionaryWithCapacity: 5];
662
+ jsNativeAd[@"title"] = ad.title;
663
+ jsNativeAd[@"advertiser"] = ad.advertiser;
664
+ jsNativeAd[@"body"] = ad.body;
665
+ jsNativeAd[@"callToAction"] = ad.callToAction;
666
+ jsNativeAd[@"starRating"] = ad.starRating;
667
+
668
+ if ( ad.icon )
669
+ {
670
+ if ( ad.icon.URL )
671
+ {
672
+ jsNativeAd[@"url"] = ad.icon.URL.absoluteString;
673
+ }
674
+ else if ( ad.icon.image )
675
+ {
676
+ NSData *imageData = UIImagePNGRepresentation(ad.icon.image);
677
+ jsNativeAd[@"imageSource"] = [imageData base64EncodedStringWithOptions: 0];
678
+ }
679
+ }
680
+
681
+ jsNativeAd[@"isOptionsViewAvailable"] = ad.optionsView ? @(YES) : @(NO);
682
+ jsNativeAd[@"isMediaViewAvailable"] = ad.mediaView ? @(YES) : @(NO);
683
+
684
+ NSMutableDictionary *adInfo = [[[AppLovinMAX shared] adInfoForAd: self.nativeAd] mutableCopy];
685
+ adInfo[@"nativeAd"] = nativeAdInfo;
686
+ adInfo[@"nativeAdImpl"] = jsNativeAd;
687
+
688
+ // Send to `AppLovinNativeAdView.js`
689
+ self.onAdLoadedEvent(adInfo);
690
+ }
691
+
692
+ - (void)didFailToLoadNativeAdForAdUnitIdentifier:(NSString *)adUnitIdentifier withError:(MAError *)error
693
+ {
694
+ [self.isLoading set: NO];
695
+
696
+ [[AppLovinMAX shared] log: @"Failed to load native ad for Ad Unit ID %@ with error: %@", self.adUnitId, error];
697
+
698
+ // Notify publisher
699
+ self.onAdLoadFailedEvent([[AppLovinMAX shared] adLoadFailedInfoForAd: adUnitIdentifier withError: error]);
700
+ }
701
+
702
+ - (void)didClickNativeAd:(MAAd *)ad
703
+ {
704
+ self.onAdClickedEvent([[AppLovinMAX shared] adInfoForAd: ad]);
705
+ }
706
+
707
+ #pragma mark - Ad Revenue Delegate
708
+
709
+ - (void)didPayRevenueForAd:(MAAd *)ad
710
+ {
711
+ self.onAdRevenuePaidEvent([[AppLovinMAX shared] adInfoForAd: ad]);
712
+ }
713
+
714
+ - (void)destroyCurrentAdIfNeeded
715
+ {
716
+ if ( self.nativeAd )
717
+ {
718
+ if ( self.nativeAd.nativeAd )
719
+ {
720
+ if ( self.nativeAd.nativeAd.mediaView )
721
+ {
722
+ [self.nativeAd.nativeAd.mediaView removeFromSuperview];
723
+ }
724
+ if ( self.nativeAd.nativeAd.optionsView )
725
+ {
726
+ [self.nativeAd.nativeAd.optionsView removeFromSuperview];
727
+ }
728
+ }
729
+
730
+ [self.adLoader destroyAd: self.nativeAd];
731
+
732
+ self.nativeAd = nil;
733
+ }
734
+
735
+ [self.clickableViews removeAllObjects];
736
+ }
737
+
738
+ @end
739
+
740
+ #ifdef RCT_NEW_ARCH_ENABLED
741
+ Class<RCTComponentViewProtocol> AppLovinMAXNativeAdViewCls(void)
742
+ {
743
+ return [AppLovinMAXNativeAdView class];
744
+ }
745
+ #endif