react-native-applovin-max 4.0.0 → 4.1.1

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.
@@ -31,6 +31,7 @@ import static com.applovin.sdk.AppLovinSdkUtils.runOnUiThreadDelayed;
31
31
 
32
32
  public class AppLovinMAXNativeAdView
33
33
  extends ReactViewGroup
34
+ implements View.OnLayoutChangeListener
34
35
  {
35
36
  private final ReactContext reactContext;
36
37
  @Nullable
@@ -39,6 +40,11 @@ public class AppLovinMAXNativeAdView
39
40
  private MaxAd nativeAd;
40
41
  private final AtomicBoolean isLoading = new AtomicBoolean(); // Guard against repeated ad loads
41
42
 
43
+ @Nullable
44
+ private View mediaView;
45
+ @Nullable
46
+ private View optionsView;
47
+
42
48
  // JavaScript properties
43
49
  private String adUnitId;
44
50
  @Nullable
@@ -135,6 +141,12 @@ public class AppLovinMAXNativeAdView
135
141
  if ( nativeAd.getNativeAd().getTitle() == null ) return;
136
142
 
137
143
  View view = findViewById( tag );
144
+ if ( view == null )
145
+ {
146
+ AppLovinMAXModule.e( "Cannot find a title view with tag \"" + tag + "\" for " + adUnitId );
147
+ return;
148
+ }
149
+
138
150
  view.setClickable( true );
139
151
 
140
152
  clickableViews.add( view );
@@ -145,6 +157,12 @@ public class AppLovinMAXNativeAdView
145
157
  if ( nativeAd.getNativeAd().getAdvertiser() == null ) return;
146
158
 
147
159
  View view = findViewById( tag );
160
+ if ( view == null )
161
+ {
162
+ AppLovinMAXModule.e( "Cannot find an advertiser view with tag \"" + tag + "\" for " + adUnitId );
163
+ return;
164
+ }
165
+
148
166
  view.setClickable( true );
149
167
 
150
168
  clickableViews.add( view );
@@ -155,6 +173,12 @@ public class AppLovinMAXNativeAdView
155
173
  if ( nativeAd.getNativeAd().getBody() == null ) return;
156
174
 
157
175
  View view = findViewById( tag );
176
+ if ( view == null )
177
+ {
178
+ AppLovinMAXModule.e( "Cannot find a body view with tag \"" + tag + "\" for " + adUnitId );
179
+ return;
180
+ }
181
+
158
182
  view.setClickable( true );
159
183
 
160
184
  clickableViews.add( view );
@@ -165,6 +189,12 @@ public class AppLovinMAXNativeAdView
165
189
  if ( nativeAd.getNativeAd().getCallToAction() == null ) return;
166
190
 
167
191
  View view = findViewById( tag );
192
+ if ( view == null )
193
+ {
194
+ AppLovinMAXModule.e( "Cannot find a callToAction view with tag \"" + tag + "\" for " + adUnitId );
195
+ return;
196
+ }
197
+
168
198
  view.setClickable( true );
169
199
 
170
200
  clickableViews.add( view );
@@ -172,7 +202,7 @@ public class AppLovinMAXNativeAdView
172
202
 
173
203
  public void setMediaView(final int tag)
174
204
  {
175
- View mediaView = nativeAd.getNativeAd().getMediaView();
205
+ mediaView = nativeAd.getNativeAd().getMediaView();
176
206
  if ( mediaView == null ) return;
177
207
 
178
208
  ViewGroup view = findViewById( tag );
@@ -184,15 +214,15 @@ public class AppLovinMAXNativeAdView
184
214
 
185
215
  clickableViews.add( view );
186
216
 
187
- mediaView.measure( MeasureSpec.makeMeasureSpec( view.getWidth(), MeasureSpec.EXACTLY ),
188
- MeasureSpec.makeMeasureSpec( view.getHeight(), MeasureSpec.EXACTLY ) );
189
- mediaView.layout( 0, 0, view.getWidth(), view.getHeight() );
217
+ view.addOnLayoutChangeListener( this );
190
218
  view.addView( mediaView );
219
+
220
+ sizeToFit( mediaView, view );
191
221
  }
192
222
 
193
223
  public void setOptionsView(final int tag)
194
224
  {
195
- View optionsView = nativeAd.getNativeAd().getOptionsView();
225
+ optionsView = nativeAd.getNativeAd().getOptionsView();
196
226
  if ( optionsView == null ) return;
197
227
 
198
228
  ViewGroup view = findViewById( tag );
@@ -202,10 +232,10 @@ public class AppLovinMAXNativeAdView
202
232
  return;
203
233
  }
204
234
 
205
- optionsView.measure( MeasureSpec.makeMeasureSpec( view.getWidth(), MeasureSpec.EXACTLY ),
206
- MeasureSpec.makeMeasureSpec( view.getHeight(), MeasureSpec.EXACTLY ) );
207
- optionsView.layout( 0, 0, view.getWidth(), view.getHeight() );
235
+ view.addOnLayoutChangeListener( this );
208
236
  view.addView( optionsView );
237
+
238
+ sizeToFit( optionsView, view );
209
239
  }
210
240
 
211
241
  public void setIconView(final int tag)
@@ -229,6 +259,23 @@ public class AppLovinMAXNativeAdView
229
259
  }
230
260
  }
231
261
 
262
+ @Override
263
+ public void onLayoutChange(View view, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom)
264
+ {
265
+ sizeToFit( mediaView, view );
266
+ sizeToFit( optionsView, view );
267
+ }
268
+
269
+ private void sizeToFit(final @Nullable View view, final View parentView)
270
+ {
271
+ if ( view != null )
272
+ {
273
+ view.measure( MeasureSpec.makeMeasureSpec( parentView.getWidth(), MeasureSpec.EXACTLY ),
274
+ MeasureSpec.makeMeasureSpec( parentView.getHeight(), MeasureSpec.EXACTLY ) );
275
+ view.layout( 0, 0, parentView.getWidth(), parentView.getHeight() );
276
+ }
277
+ }
278
+
232
279
  /// Ad Loader Callback
233
280
 
234
281
  class NativeAdListener
@@ -245,7 +292,7 @@ public class AppLovinMAXNativeAdView
245
292
  isLoading.set( false );
246
293
 
247
294
  AppLovinMAXModule.e( "Native ad is of template type, failing ad load..." );
248
- AppLovinMAXModule.getInstance().handleNativeAdLoadFailureForAdUnitId( adUnitId, null );
295
+ AppLovinMAXModule.getInstance().sendReactNativeEventForAdLoadFailed( "OnNativeAdLoadFailedEvent", adUnitId, null );
249
296
 
250
297
  return;
251
298
  }
@@ -262,8 +309,12 @@ public class AppLovinMAXNativeAdView
262
309
  // Notify publisher
263
310
  AppLovinMAXModule.getInstance().onAdLoaded( ad );
264
311
 
265
- adLoader.a( clickableViews, AppLovinMAXNativeAdView.this, ad );
266
- adLoader.b( ad );
312
+ // Loader can be null when the user hides before the properties are fully set
313
+ if ( adLoader != null )
314
+ {
315
+ adLoader.a( clickableViews, AppLovinMAXNativeAdView.this, ad );
316
+ adLoader.b( ad );
317
+ }
267
318
 
268
319
  isLoading.set( false );
269
320
  }, 500L );
@@ -277,7 +328,7 @@ public class AppLovinMAXNativeAdView
277
328
  AppLovinMAXModule.e( "Failed to load native ad for Ad Unit ID " + adUnitId + " with error: " + error );
278
329
 
279
330
  // Notify publisher
280
- AppLovinMAXModule.getInstance().handleNativeAdLoadFailureForAdUnitId( adUnitId, error );
331
+ AppLovinMAXModule.getInstance().sendReactNativeEventForAdLoadFailed( "OnNativeAdLoadFailedEvent", adUnitId, error );
281
332
  }
282
333
 
283
334
  @Override
@@ -334,23 +385,23 @@ public class AppLovinMAXNativeAdView
334
385
  {
335
386
  if ( nativeAd.getNativeAd() != null )
336
387
  {
337
- View view = nativeAd.getNativeAd().getMediaView();
338
- if ( view != null )
388
+ if ( mediaView != null )
339
389
  {
340
- ViewGroup parentView = (ViewGroup) view.getParent();
390
+ ViewGroup parentView = (ViewGroup) mediaView.getParent();
341
391
  if ( parentView != null )
342
392
  {
343
- parentView.removeView( view );
393
+ parentView.removeOnLayoutChangeListener( AppLovinMAXNativeAdView.this );
394
+ parentView.removeView( mediaView );
344
395
  }
345
396
  }
346
397
 
347
- view = nativeAd.getNativeAd().getOptionsView();
348
- if ( view != null )
398
+ if ( optionsView != null )
349
399
  {
350
- ViewGroup parentView = (ViewGroup) view.getParent();
400
+ ViewGroup parentView = (ViewGroup) optionsView.getParent();
351
401
  if ( parentView != null )
352
402
  {
353
- parentView.removeView( view );
403
+ parentView.removeOnLayoutChangeListener( AppLovinMAXNativeAdView.this );
404
+ parentView.removeView( optionsView );
354
405
  }
355
406
  }
356
407
  }
package/ios/AppLovinMAX.h CHANGED
@@ -37,9 +37,9 @@ NS_ASSUME_NONNULL_BEGIN
37
37
  - (void)log:(NSString *)format, ...;
38
38
 
39
39
  /**
40
- * Convenience method for invoking a native ad load failure event.
40
+ * Convenience method for invoking an ad load failure event.
41
41
  */
42
- - (void)handleNativeAdLoadFailureForAdUnitIdentifier:(NSString *)adUnitIdentifier error:(nullable MAError *)error;
42
+ - (void)sendReactNativeEventForAdLoadFailed:(NSString *)name forAdUnitIdentifier:(NSString *)adUnitIdentifier withError:(nullable MAError *)error;
43
43
 
44
44
  @end
45
45
 
package/ios/AppLovinMAX.m CHANGED
@@ -48,9 +48,18 @@
48
48
  @property (nonatomic, strong, nullable) NSURL *privacyPolicyURLToSet;
49
49
  @property (nonatomic, strong, nullable) NSURL *termsOfServiceURLToSet;
50
50
 
51
+ @property (nonatomic, strong, nullable) NSNumber *targetingYearOfBirthToSet;
52
+ @property (nonatomic, copy, nullable) NSString *targetingGenderToSet;
53
+ @property (nonatomic, strong, nullable) NSNumber *targetingMaximumAdContentRatingToSet;
54
+ @property (nonatomic, copy, nullable) NSString *targetingEmailToSet;
55
+ @property (nonatomic, copy, nullable) NSString *targetingPhoneNumberToSet;
56
+ @property (nonatomic, strong, nullable) NSArray<NSString *> *targetingKeywordsToSet;
57
+ @property (nonatomic, strong, nullable) NSArray<NSString *> *targetingInterestsToSet;
58
+
51
59
  // Fullscreen Ad Fields
52
60
  @property (nonatomic, strong) NSMutableDictionary<NSString *, MAInterstitialAd *> *interstitials;
53
61
  @property (nonatomic, strong) NSMutableDictionary<NSString *, MARewardedAd *> *rewardedAds;
62
+ @property (nonatomic, strong) NSMutableDictionary<NSString *, MAAppOpenAd *> *appOpenAds;
54
63
 
55
64
  // Banner Fields
56
65
  @property (nonatomic, strong) NSMutableDictionary<NSString *, MAAdView *> *adViews;
@@ -105,6 +114,7 @@ RCT_EXPORT_MODULE()
105
114
  self.interstitials = [NSMutableDictionary dictionaryWithCapacity: 2];
106
115
  self.rewardedAds = [NSMutableDictionary dictionaryWithCapacity: 2];
107
116
  self.adViews = [NSMutableDictionary dictionaryWithCapacity: 2];
117
+ self.appOpenAds = [NSMutableDictionary dictionaryWithCapacity: 2];
108
118
  self.adViewAdFormats = [NSMutableDictionary dictionaryWithCapacity: 2];
109
119
  self.adViewPositions = [NSMutableDictionary dictionaryWithCapacity: 2];
110
120
  self.adViewOffsets = [NSMutableDictionary dictionaryWithCapacity: 2];
@@ -205,7 +215,49 @@ RCT_EXPORT_METHOD(initialize:(NSString *)pluginVersion :(NSString *)sdkKey :(RCT
205
215
  self.sdk.settings.locationCollectionEnabled = self.locationCollectionEnabledToSet.boolValue;
206
216
  self.locationCollectionEnabledToSet = nil;
207
217
  }
208
-
218
+
219
+ if ( self.targetingYearOfBirthToSet )
220
+ {
221
+ self.sdk.targetingData.yearOfBirth = self.targetingYearOfBirthToSet.intValue <= 0 ? nil : self.targetingYearOfBirthToSet;
222
+ self.targetingYearOfBirthToSet = nil;
223
+ }
224
+
225
+ if ( self.targetingGenderToSet )
226
+ {
227
+ self.sdk.targetingData.gender = [self toAppLovinGender: self.targetingGenderToSet];
228
+ self.targetingGenderToSet = nil;
229
+ }
230
+
231
+ if ( self.targetingMaximumAdContentRatingToSet )
232
+ {
233
+ self.sdk.targetingData.maximumAdContentRating = [self toAppLovinAdContentRating: self.targetingMaximumAdContentRatingToSet];
234
+ self.targetingMaximumAdContentRatingToSet = nil;
235
+ }
236
+
237
+ if ( self.targetingEmailToSet )
238
+ {
239
+ self.sdk.targetingData.email = self.targetingEmailToSet;
240
+ self.targetingEmailToSet = nil;
241
+ }
242
+
243
+ if ( self.targetingPhoneNumberToSet )
244
+ {
245
+ self.sdk.targetingData.phoneNumber = self.targetingPhoneNumberToSet;
246
+ self.targetingPhoneNumberToSet = nil;
247
+ }
248
+
249
+ if ( self.targetingKeywordsToSet )
250
+ {
251
+ self.sdk.targetingData.keywords = self.targetingKeywordsToSet;
252
+ self.targetingKeywordsToSet = nil;
253
+ }
254
+
255
+ if ( self.targetingInterestsToSet )
256
+ {
257
+ self.sdk.targetingData.interests = self.targetingInterestsToSet;
258
+ self.targetingInterestsToSet = nil;
259
+ }
260
+
209
261
  [self setPendingExtraParametersIfNeeded: self.sdk.settings];
210
262
 
211
263
  [self.sdk initializeSdkWithCompletionHandler:^(ALSdkConfiguration *configuration) {
@@ -389,7 +441,7 @@ RCT_EXPORT_METHOD(setTargetingDataYearOfBirth:(nonnull NSNumber *)yearOfBirth)
389
441
  {
390
442
  if ( !self.sdk )
391
443
  {
392
- [self logUninitializedAccessError: @"setTargetingDataYearOfBirth"];
444
+ self.targetingYearOfBirthToSet = yearOfBirth;
393
445
  return;
394
446
  }
395
447
 
@@ -400,61 +452,29 @@ RCT_EXPORT_METHOD(setTargetingDataGender:(nullable NSString *)gender)
400
452
  {
401
453
  if ( !self.sdk )
402
454
  {
403
- [self logUninitializedAccessError: @"setTargetingDataGender"];
455
+ self.targetingGenderToSet = gender;
404
456
  return;
405
457
  }
406
458
 
407
- ALGender alGender = ALGenderUnknown;
408
-
409
- if ( [@"F" isEqualToString: gender] )
410
- {
411
- alGender = ALGenderFemale;
412
- }
413
- else if ( [@"M" isEqualToString: gender] )
414
- {
415
- alGender = ALGenderMale;
416
- }
417
- else if ( [@"O" isEqualToString: gender] )
418
- {
419
- alGender = ALGenderOther;
420
- }
421
-
422
- self.sdk.targetingData.gender = alGender;
459
+ self.sdk.targetingData.gender = [self toAppLovinGender: gender];
423
460
  }
424
461
 
425
462
  RCT_EXPORT_METHOD(setTargetingDataMaximumAdContentRating:(nonnull NSNumber *)maximumAdContentRating)
426
463
  {
427
464
  if ( !self.sdk )
428
465
  {
429
- [self logUninitializedAccessError: @"setTargetingDataMaximumAdContentRating"];
466
+ self.targetingMaximumAdContentRatingToSet = maximumAdContentRating;
430
467
  return;
431
468
  }
432
469
 
433
- ALAdContentRating rating = ALAdContentRatingNone;
434
-
435
- int intVal = maximumAdContentRating.intValue;
436
-
437
- if ( intVal == 1 )
438
- {
439
- rating = ALAdContentRatingAllAudiences;
440
- }
441
- else if ( intVal == 2 )
442
- {
443
- rating = ALAdContentRatingEveryoneOverTwelve;
444
- }
445
- else if ( intVal == 3 )
446
- {
447
- rating = ALAdContentRatingMatureAudiences;
448
- }
449
-
450
- self.sdk.targetingData.maximumAdContentRating = rating;
470
+ self.sdk.targetingData.maximumAdContentRating = [self toAppLovinAdContentRating: maximumAdContentRating];
451
471
  }
452
472
 
453
473
  RCT_EXPORT_METHOD(setTargetingDataEmail:(nullable NSString *)email)
454
474
  {
455
475
  if ( !self.sdk )
456
476
  {
457
- [self logUninitializedAccessError: @"setTargetingDataEmail"];
477
+ self.targetingEmailToSet = email;
458
478
  return;
459
479
  }
460
480
 
@@ -465,7 +485,7 @@ RCT_EXPORT_METHOD(setTargetingDataPhoneNumber:(nullable NSString *)phoneNumber)
465
485
  {
466
486
  if ( !self.sdk )
467
487
  {
468
- [self logUninitializedAccessError: @"setTargetingDataPhoneNumber"];
488
+ self.targetingPhoneNumberToSet = phoneNumber;
469
489
  return;
470
490
  }
471
491
 
@@ -476,7 +496,7 @@ RCT_EXPORT_METHOD(setTargetingDataKeywords:(nullable NSArray<NSString *> *)keywo
476
496
  {
477
497
  if ( !self.sdk )
478
498
  {
479
- [self logUninitializedAccessError: @"setTargetingDataKeywords"];
499
+ self.targetingKeywordsToSet = keywords;
480
500
  return;
481
501
  }
482
502
 
@@ -487,7 +507,7 @@ RCT_EXPORT_METHOD(setTargetingDataInterests:(nullable NSArray<NSString *> *)inte
487
507
  {
488
508
  if ( !self.sdk )
489
509
  {
490
- [self logUninitializedAccessError: @"setTargetingDataInterests"];
510
+ self.targetingInterestsToSet = interests;
491
511
  return;
492
512
  }
493
513
 
@@ -498,7 +518,13 @@ RCT_EXPORT_METHOD(clearAllTargetingData)
498
518
  {
499
519
  if ( !self.sdk )
500
520
  {
501
- [self logUninitializedAccessError: @"clearAllTargetingData"];
521
+ self.targetingYearOfBirthToSet = nil;
522
+ self.targetingGenderToSet = nil;
523
+ self.targetingMaximumAdContentRatingToSet = nil;
524
+ self.targetingEmailToSet = nil;
525
+ self.targetingPhoneNumberToSet = nil;
526
+ self.targetingKeywordsToSet = nil;
527
+ self.targetingInterestsToSet = nil;
502
528
  return;
503
529
  }
504
530
 
@@ -702,6 +728,32 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
702
728
  [rewardedAd setExtraParameterForKey: key value: value];
703
729
  }
704
730
 
731
+ #pragma mark - App Open Ad
732
+
733
+ RCT_EXPORT_METHOD(loadAppOpenAd:(NSString *)adUnitIdentifier)
734
+ {
735
+ MAAppOpenAd *appOpenAd = [self retrieveAppOpenAdForAdUnitIdentifier: adUnitIdentifier];
736
+ [appOpenAd loadAd];
737
+ }
738
+
739
+ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(isAppOpenAdReady:(NSString *)adUnitIdentifier)
740
+ {
741
+ MAAppOpenAd *appOpenAd = [self retrieveAppOpenAdForAdUnitIdentifier: adUnitIdentifier];
742
+ return @([appOpenAd isReady]);
743
+ }
744
+
745
+ RCT_EXPORT_METHOD(showAppOpenAd:(NSString *)adUnitIdentifier placement:(nullable NSString *)placement customData:(nullable NSString *)customData)
746
+ {
747
+ MAAppOpenAd *appOpenAd = [self retrieveAppOpenAdForAdUnitIdentifier: adUnitIdentifier];
748
+ [appOpenAd showAdForPlacement: placement customData: customData];
749
+ }
750
+
751
+ RCT_EXPORT_METHOD(setAppOpenAdExtraParameter:(NSString *)adUnitIdentifier key:(NSString *)key value:(nullable NSString *)value)
752
+ {
753
+ MAAppOpenAd *appOpenAd = [self retrieveAppOpenAdForAdUnitIdentifier: adUnitIdentifier];
754
+ [appOpenAd setExtraParameterForKey: key value: value];
755
+ }
756
+
705
757
  #pragma mark - Ad Callbacks
706
758
 
707
759
  - (void)didLoadAd:(MAAd *)ad
@@ -736,6 +788,10 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
736
788
  {
737
789
  name = @"OnNativeAdLoadedEvent";
738
790
  }
791
+ else if ( MAAdFormat.appOpen == adFormat )
792
+ {
793
+ name = @"OnAppOpenAdLoadedEvent";
794
+ }
739
795
  else
740
796
  {
741
797
  [self logInvalidAdFormat: adFormat];
@@ -745,14 +801,19 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
745
801
  [self sendReactNativeEventWithName: name body: [self adInfoForAd: ad]];
746
802
  }
747
803
 
748
- - (void)handleNativeAdLoadFailureForAdUnitIdentifier:(NSString *)adUnitIdentifier error:(nullable MAError *)error
804
+ - (void)sendReactNativeEventForAdLoadFailed:(NSString *)name forAdUnitIdentifier:(NSString *)adUnitIdentifier withError:(nullable MAError *)error
749
805
  {
750
- [self sendReactNativeEventWithName: @"OnNativeAdLoadFailedEvent"
751
- body: @{@"adUnitId" : adUnitIdentifier,
752
- @"code" : @(error.code),
753
- @"message" : error.message,
754
- @"adLoadFailureInfo" : error.adLoadFailureInfo ?: @"",
755
- @"waterfall": [self createAdWaterfallInfo: error.waterfall]}];
806
+ NSDictionary *body = ( error ) ?
807
+ @{@"adUnitId": adUnitIdentifier,
808
+ @"code" : @(error.code),
809
+ @"message" : error.message,
810
+ @"adLoadFailureInfo" : error.adLoadFailureInfo ?: @"",
811
+ @"waterfall": [self createAdWaterfallInfo: error.waterfall]}
812
+ :
813
+ @{@"adUnitId": adUnitIdentifier,
814
+ @"code" : @(MAErrorCodeUnspecified)};
815
+
816
+ [self sendReactNativeEventWithName: name body: body];
756
817
  }
757
818
 
758
819
  - (void)didFailToLoadAdForAdUnitIdentifier:(NSString *)adUnitIdentifier withError:(MAError *)error
@@ -776,17 +837,17 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
776
837
  {
777
838
  name = @"OnRewardedAdLoadFailedEvent";
778
839
  }
840
+ else if ( self.appOpenAds[adUnitIdentifier] )
841
+ {
842
+ name = @"OnAppOpenAdLoadFailedEvent";
843
+ }
779
844
  else
780
845
  {
781
846
  [self log: @"invalid adUnitId from %@", [NSThread callStackSymbols]];
782
847
  return;
783
848
  }
784
849
 
785
- [self sendReactNativeEventWithName: name body: @{@"adUnitId" : adUnitIdentifier,
786
- @"code" : @(error.code),
787
- @"message" : error.message,
788
- @"adLoadFailureInfo" : error.adLoadFailureInfo ?: @"",
789
- @"waterfall": [self createAdWaterfallInfo: error.waterfall]}];
850
+ [self sendReactNativeEventForAdLoadFailed: name forAdUnitIdentifier: adUnitIdentifier withError: error];
790
851
  }
791
852
 
792
853
  - (void)didClickAd:(MAAd *)ad
@@ -813,6 +874,10 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
813
874
  {
814
875
  name = @"OnNativeAdClickedEvent";
815
876
  }
877
+ else if ( MAAdFormat.appOpen == adFormat )
878
+ {
879
+ name = @"OnAppOpenAdClickedEvent";
880
+ }
816
881
  else
817
882
  {
818
883
  [self logInvalidAdFormat: adFormat];
@@ -826,17 +891,21 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
826
891
  {
827
892
  // BMLs do not support [DISPLAY] events in Unity
828
893
  MAAdFormat *adFormat = ad.format;
829
- if ( adFormat != MAAdFormat.interstitial && adFormat != MAAdFormat.rewarded ) return;
894
+ if ( adFormat != MAAdFormat.interstitial && adFormat != MAAdFormat.rewarded && adFormat != MAAdFormat.appOpen ) return;
830
895
 
831
896
  NSString *name;
832
897
  if ( MAAdFormat.interstitial == adFormat )
833
898
  {
834
899
  name = @"OnInterstitialDisplayedEvent";
835
900
  }
836
- else // REWARDED
901
+ else if ( MAAdFormat.rewarded == adFormat )
837
902
  {
838
903
  name = @"OnRewardedAdDisplayedEvent";
839
904
  }
905
+ else // APP OPEN
906
+ {
907
+ name = @"OnAppOpenAdDisplayedEvent";
908
+ }
840
909
 
841
910
  [self sendReactNativeEventWithName: name body: [self adInfoForAd: ad]];
842
911
  }
@@ -845,17 +914,21 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
845
914
  {
846
915
  // BMLs do not support [DISPLAY] events in Unity
847
916
  MAAdFormat *adFormat = ad.format;
848
- if ( adFormat != MAAdFormat.interstitial && adFormat != MAAdFormat.rewarded ) return;
917
+ if ( adFormat != MAAdFormat.interstitial && adFormat != MAAdFormat.rewarded && adFormat != MAAdFormat.appOpen ) return;
849
918
 
850
919
  NSString *name;
851
920
  if ( MAAdFormat.interstitial == adFormat )
852
921
  {
853
922
  name = @"OnInterstitialAdFailedToDisplayEvent";
854
923
  }
855
- else // REWARDED
924
+ else if ( MAAdFormat.rewarded == adFormat )
856
925
  {
857
926
  name = @"OnRewardedAdFailedToDisplayEvent";
858
927
  }
928
+ else // APP OPEN
929
+ {
930
+ name = @"OnAppOpenAdFailedToDisplayEvent";
931
+ }
859
932
 
860
933
  NSMutableDictionary *body = [@{@"code" : @(error.code),
861
934
  @"message" : error.message} mutableCopy];
@@ -868,17 +941,21 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
868
941
  {
869
942
  // BMLs do not support [HIDDEN] events in Unity
870
943
  MAAdFormat *adFormat = ad.format;
871
- if ( adFormat != MAAdFormat.interstitial && adFormat != MAAdFormat.rewarded ) return;
944
+ if ( adFormat != MAAdFormat.interstitial && adFormat != MAAdFormat.rewarded && adFormat != MAAdFormat.appOpen ) return;
872
945
 
873
946
  NSString *name;
874
947
  if ( MAAdFormat.interstitial == adFormat )
875
948
  {
876
949
  name = @"OnInterstitialHiddenEvent";
877
950
  }
878
- else // REWARDED
951
+ else if ( MAAdFormat.rewarded == adFormat )
879
952
  {
880
953
  name = @"OnRewardedAdHiddenEvent";
881
954
  }
955
+ else // APP OPEN
956
+ {
957
+ name = @"OnAppOpenAdHiddenEvent";
958
+ }
882
959
 
883
960
  [self sendReactNativeEventWithName: name body: [self adInfoForAd: ad]];
884
961
  }
@@ -933,6 +1010,10 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
933
1010
  {
934
1011
  name = @"OnNativeAdRevenuePaid";
935
1012
  }
1013
+ else if ( MAAdFormat.appOpen == adFormat )
1014
+ {
1015
+ name = @"OnAppOpenAdRevenuePaid";
1016
+ }
936
1017
  else
937
1018
  {
938
1019
  [self logInvalidAdFormat: adFormat];
@@ -1228,6 +1309,21 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1228
1309
  return result;
1229
1310
  }
1230
1311
 
1312
+ - (MAAppOpenAd *)retrieveAppOpenAdForAdUnitIdentifier:(NSString *)adUnitIdentifier
1313
+ {
1314
+ MAAppOpenAd *result = self.appOpenAds[adUnitIdentifier];
1315
+ if ( !result )
1316
+ {
1317
+ result = [[MAAppOpenAd alloc] initWithAdUnitIdentifier: adUnitIdentifier sdk: self.sdk];
1318
+ result.delegate = self;
1319
+ result.revenueDelegate = self;
1320
+
1321
+ self.appOpenAds[adUnitIdentifier] = result;
1322
+ }
1323
+
1324
+ return result;
1325
+ }
1326
+
1231
1327
  - (MAAdView *)retrieveAdViewForAdUnitIdentifier:(NSString *)adUnitIdentifier adFormat:(MAAdFormat *)adFormat
1232
1328
  {
1233
1329
  return [self retrieveAdViewForAdUnitIdentifier: adUnitIdentifier adFormat: adFormat atPosition: nil withOffset: CGPointZero];
@@ -1483,6 +1579,50 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1483
1579
  NSLog(@"[%@] [%@] %@", SDK_TAG, TAG, message);
1484
1580
  }
1485
1581
 
1582
+ - (ALGender)toAppLovinGender:(nullable NSString *)gender
1583
+ {
1584
+ if ( gender )
1585
+ {
1586
+ if ( [@"F" al_isEqualToStringIgnoringCase: gender] )
1587
+ {
1588
+ return ALGenderFemale;
1589
+ }
1590
+ else if ( [@"M" al_isEqualToStringIgnoringCase: gender] )
1591
+ {
1592
+ return ALGenderMale;
1593
+ }
1594
+ else if ( [@"O" al_isEqualToStringIgnoringCase: gender] )
1595
+ {
1596
+ return ALGenderOther;
1597
+ }
1598
+ }
1599
+
1600
+ return ALGenderUnknown;
1601
+ }
1602
+
1603
+ - (ALAdContentRating)toAppLovinAdContentRating:(nullable NSNumber *)maximumAdContentRating
1604
+ {
1605
+ if ( maximumAdContentRating )
1606
+ {
1607
+ int intVal = maximumAdContentRating.intValue;
1608
+
1609
+ if ( intVal == 1 )
1610
+ {
1611
+ return ALAdContentRatingAllAudiences;
1612
+ }
1613
+ else if ( intVal == 2 )
1614
+ {
1615
+ return ALAdContentRatingEveryoneOverTwelve;
1616
+ }
1617
+ else if ( intVal == 3 )
1618
+ {
1619
+ return ALAdContentRatingMatureAudiences;
1620
+ }
1621
+ }
1622
+
1623
+ return ALAdContentRatingNone;
1624
+ }
1625
+
1486
1626
  #pragma mark - Ad Info
1487
1627
 
1488
1628
  - (NSDictionary<NSString *, id> *)adInfoForAd:(MAAd *)ad
@@ -1599,6 +1739,14 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1599
1739
  @"OnRewardedAdReceivedRewardEvent",
1600
1740
  @"OnRewardedAdRevenuePaid",
1601
1741
 
1742
+ @"OnAppOpenAdLoadedEvent",
1743
+ @"OnAppOpenAdLoadFailedEvent",
1744
+ @"OnAppOpenAdClickedEvent",
1745
+ @"OnAppOpenAdDisplayedEvent",
1746
+ @"OnAppOpenAdFailedToDisplayEvent",
1747
+ @"OnAppOpenAdHiddenEvent",
1748
+ @"OnAppOpenAdRevenuePaid",
1749
+
1602
1750
  @"OnNativeAdLoadedEvent",
1603
1751
  @"OnNativeAdLoadFailedEvent",
1604
1752
  @"OnNativeAdClickedEvent",