react-native-applovin-max 3.1.0 → 3.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ios/AppLovinMAX.h CHANGED
@@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN
19
19
  /**
20
20
  * The primary bridge between JS <-> native code for the AppLovin MAX React Native module.
21
21
  */
22
- @interface AppLovinMAX : RCTEventEmitter<RCTBridgeModule, MAAdDelegate, MARewardedAdDelegate, MAAdViewAdDelegate>
22
+ @interface AppLovinMAX : RCTEventEmitter<RCTBridgeModule, MAAdDelegate, MARewardedAdDelegate, MAAdViewAdDelegate, MAAdRevenueDelegate>
23
23
 
24
24
  /**
25
25
  * Shared instance of this bridge module.
package/ios/AppLovinMAX.m CHANGED
@@ -206,139 +206,6 @@ RCT_EXPORT_METHOD(initialize:(NSString *)pluginVersion :(NSString *)sdkKey :(RCT
206
206
  }];
207
207
  }
208
208
 
209
- #pragma mark - Data Passing
210
-
211
- RCT_EXPORT_METHOD(setTargetingDataYearOfBirth:(nonnull NSNumber *)yearOfBirth)
212
- {
213
- if ( !_sdk )
214
- {
215
- [self logUninitializedAccessError: @"setTargetingDataYearOfBirth"];
216
- return;
217
- }
218
-
219
- self.sdk.targetingData.yearOfBirth = yearOfBirth.intValue <= 0 ? nil : yearOfBirth;
220
- }
221
-
222
- RCT_EXPORT_METHOD(setTargetingDataGender:(nullable NSString *)gender)
223
- {
224
- if ( !_sdk )
225
- {
226
- [self logUninitializedAccessError: @"setTargetingDataGender"];
227
- return;
228
- }
229
-
230
- ALGender alGender = ALGenderUnknown;
231
-
232
- if ( [@"F" isEqualToString: gender] )
233
- {
234
- alGender = ALGenderFemale;
235
- }
236
- else if ( [@"M" isEqualToString: gender] )
237
- {
238
- alGender = ALGenderMale;
239
- }
240
- else if ( [@"O" isEqualToString: gender] )
241
- {
242
- alGender = ALGenderOther;
243
- }
244
-
245
- self.sdk.targetingData.gender = alGender;
246
- }
247
-
248
- RCT_EXPORT_METHOD(setTargetingDataMaximumAdContentRating:(nonnull NSNumber *)maximumAdContentRating)
249
- {
250
- if ( !_sdk )
251
- {
252
- [self logUninitializedAccessError: @"setTargetingDataMaximumAdContentRating"];
253
- return;
254
- }
255
-
256
- ALAdContentRating rating = ALAdContentRatingNone;
257
-
258
- int intVal = maximumAdContentRating.intValue;
259
-
260
- if ( intVal == 1 )
261
- {
262
- rating = ALAdContentRatingAllAudiences;
263
- }
264
- else if ( intVal == 2 )
265
- {
266
- rating = ALAdContentRatingEveryoneOverTwelve;
267
- }
268
- else if ( intVal == 3 )
269
- {
270
- rating = ALAdContentRatingMatureAudiences;
271
- }
272
-
273
- self.sdk.targetingData.maximumAdContentRating = rating;
274
- }
275
-
276
- RCT_EXPORT_METHOD(setTargetingDataEmail:(nullable NSString *)email)
277
- {
278
- if ( !_sdk )
279
- {
280
- [self logUninitializedAccessError: @"setTargetingDataEmail"];
281
- return;
282
- }
283
-
284
- self.sdk.targetingData.email = email;
285
- }
286
-
287
- RCT_EXPORT_METHOD(setTargetingDataPhoneNumber:(nullable NSString *)phoneNumber)
288
- {
289
- if ( !_sdk )
290
- {
291
- [self logUninitializedAccessError: @"setTargetingDataPhoneNumber"];
292
- return;
293
- }
294
-
295
- self.sdk.targetingData.phoneNumber = phoneNumber;
296
- }
297
-
298
- RCT_EXPORT_METHOD(setTargetingDataKeywords:(nullable NSArray<NSString *> *)keywords)
299
- {
300
- if ( !_sdk )
301
- {
302
- [self logUninitializedAccessError: @"setTargetingDataKeywords"];
303
- return;
304
- }
305
-
306
- self.sdk.targetingData.keywords = keywords;
307
- }
308
-
309
- RCT_EXPORT_METHOD(setTargetingDataInterests:(nullable NSArray<NSString *> *)interests)
310
- {
311
- if ( !_sdk )
312
- {
313
- [self logUninitializedAccessError: @"setTargetingDataInterests"];
314
- return;
315
- }
316
-
317
- self.sdk.targetingData.interests = interests;
318
- }
319
-
320
- RCT_EXPORT_METHOD(clearAllTargetingData)
321
- {
322
- if ( !_sdk )
323
- {
324
- [self logUninitializedAccessError: @"clearAllTargetingData"];
325
- return;
326
- }
327
-
328
- [self.sdk.targetingData clearAll];
329
- }
330
-
331
- RCT_EXPORT_METHOD(setLocationCollectionEnabled:(BOOL)locationCollectionEnabled)
332
- {
333
- if ( !_sdk )
334
- {
335
- [self logUninitializedAccessError: @"setLocationCollectionEnabled"];
336
- return;
337
- }
338
-
339
- self.sdk.settings.locationCollectionEnabled = locationCollectionEnabled;
340
- }
341
-
342
209
  #pragma mark - General Public API
343
210
 
344
211
  RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(isTablet)
@@ -360,7 +227,7 @@ RCT_EXPORT_METHOD(showMediationDebugger)
360
227
  RCT_EXPORT_METHOD(showConsentDialog:(RCTResponseSenderBlock)callback)
361
228
  {
362
229
  [self log: @"Failed to show consent dialog - Unavailable on iOS, please use the consent flow: https://dash.applovin.com/documentation/mediation/react-native/getting-started/consent-flow"];
363
-
230
+
364
231
  callback(nil);
365
232
  }
366
233
 
@@ -482,6 +349,150 @@ RCT_EXPORT_METHOD(setTermsOfServiceUrl:(NSString *)urlString)
482
349
  self.termsOfServiceURLToSet = [NSURL URLWithString: urlString];
483
350
  }
484
351
 
352
+ #pragma mark - Data Passing
353
+
354
+ RCT_EXPORT_METHOD(setUserSegment:(nullable NSString *)name)
355
+ {
356
+ if ( !_sdk )
357
+ {
358
+ [self logUninitializedAccessError: @"setUserSegment"];
359
+ return;
360
+ }
361
+
362
+ self.sdk.userSegment.name = name;
363
+ }
364
+
365
+ RCT_EXPORT_METHOD(setTargetingDataYearOfBirth:(nonnull NSNumber *)yearOfBirth)
366
+ {
367
+ if ( !_sdk )
368
+ {
369
+ [self logUninitializedAccessError: @"setTargetingDataYearOfBirth"];
370
+ return;
371
+ }
372
+
373
+ self.sdk.targetingData.yearOfBirth = yearOfBirth.intValue <= 0 ? nil : yearOfBirth;
374
+ }
375
+
376
+ RCT_EXPORT_METHOD(setTargetingDataGender:(nullable NSString *)gender)
377
+ {
378
+ if ( !_sdk )
379
+ {
380
+ [self logUninitializedAccessError: @"setTargetingDataGender"];
381
+ return;
382
+ }
383
+
384
+ ALGender alGender = ALGenderUnknown;
385
+
386
+ if ( [@"F" isEqualToString: gender] )
387
+ {
388
+ alGender = ALGenderFemale;
389
+ }
390
+ else if ( [@"M" isEqualToString: gender] )
391
+ {
392
+ alGender = ALGenderMale;
393
+ }
394
+ else if ( [@"O" isEqualToString: gender] )
395
+ {
396
+ alGender = ALGenderOther;
397
+ }
398
+
399
+ self.sdk.targetingData.gender = alGender;
400
+ }
401
+
402
+ RCT_EXPORT_METHOD(setTargetingDataMaximumAdContentRating:(nonnull NSNumber *)maximumAdContentRating)
403
+ {
404
+ if ( !_sdk )
405
+ {
406
+ [self logUninitializedAccessError: @"setTargetingDataMaximumAdContentRating"];
407
+ return;
408
+ }
409
+
410
+ ALAdContentRating rating = ALAdContentRatingNone;
411
+
412
+ int intVal = maximumAdContentRating.intValue;
413
+
414
+ if ( intVal == 1 )
415
+ {
416
+ rating = ALAdContentRatingAllAudiences;
417
+ }
418
+ else if ( intVal == 2 )
419
+ {
420
+ rating = ALAdContentRatingEveryoneOverTwelve;
421
+ }
422
+ else if ( intVal == 3 )
423
+ {
424
+ rating = ALAdContentRatingMatureAudiences;
425
+ }
426
+
427
+ self.sdk.targetingData.maximumAdContentRating = rating;
428
+ }
429
+
430
+ RCT_EXPORT_METHOD(setTargetingDataEmail:(nullable NSString *)email)
431
+ {
432
+ if ( !_sdk )
433
+ {
434
+ [self logUninitializedAccessError: @"setTargetingDataEmail"];
435
+ return;
436
+ }
437
+
438
+ self.sdk.targetingData.email = email;
439
+ }
440
+
441
+ RCT_EXPORT_METHOD(setTargetingDataPhoneNumber:(nullable NSString *)phoneNumber)
442
+ {
443
+ if ( !_sdk )
444
+ {
445
+ [self logUninitializedAccessError: @"setTargetingDataPhoneNumber"];
446
+ return;
447
+ }
448
+
449
+ self.sdk.targetingData.phoneNumber = phoneNumber;
450
+ }
451
+
452
+ RCT_EXPORT_METHOD(setTargetingDataKeywords:(nullable NSArray<NSString *> *)keywords)
453
+ {
454
+ if ( !_sdk )
455
+ {
456
+ [self logUninitializedAccessError: @"setTargetingDataKeywords"];
457
+ return;
458
+ }
459
+
460
+ self.sdk.targetingData.keywords = keywords;
461
+ }
462
+
463
+ RCT_EXPORT_METHOD(setTargetingDataInterests:(nullable NSArray<NSString *> *)interests)
464
+ {
465
+ if ( !_sdk )
466
+ {
467
+ [self logUninitializedAccessError: @"setTargetingDataInterests"];
468
+ return;
469
+ }
470
+
471
+ self.sdk.targetingData.interests = interests;
472
+ }
473
+
474
+ RCT_EXPORT_METHOD(clearAllTargetingData)
475
+ {
476
+ if ( !_sdk )
477
+ {
478
+ [self logUninitializedAccessError: @"clearAllTargetingData"];
479
+ return;
480
+ }
481
+
482
+ [self.sdk.targetingData clearAll];
483
+ }
484
+
485
+ RCT_EXPORT_METHOD(setLocationCollectionEnabled:(BOOL)locationCollectionEnabled)
486
+ {
487
+ if ( !_sdk )
488
+ {
489
+ [self logUninitializedAccessError: @"setLocationCollectionEnabled"];
490
+ return;
491
+ }
492
+
493
+ self.sdk.settings.locationCollectionEnabled = locationCollectionEnabled;
494
+ }
495
+
485
496
  #pragma mark - Event Tracking
486
497
 
487
498
  RCT_EXPORT_METHOD(trackEvent:(NSString *)event :(NSDictionary<NSString *, id> *)parameters)
@@ -512,6 +523,11 @@ RCT_EXPORT_METHOD(setBannerPlacement:(NSString *)adUnitIdentifier :(nullable NSS
512
523
  [self setAdViewPlacement: placement forAdUnitIdentifier: adUnitIdentifier adFormat: DEVICE_SPECIFIC_ADVIEW_AD_FORMAT];
513
524
  }
514
525
 
526
+ RCT_EXPORT_METHOD(setBannerCustomData:(NSString *)adUnitIdentifier :(nullable NSString *)customData)
527
+ {
528
+ [self setAdViewCustomData: customData forAdUnitIdentifier: adUnitIdentifier adFormat: DEVICE_SPECIFIC_ADVIEW_AD_FORMAT];
529
+ }
530
+
515
531
  RCT_EXPORT_METHOD(updateBannerPosition:(NSString *)adUnitIdentifier :(NSString *)bannerPosition)
516
532
  {
517
533
  [self updateAdViewPosition: bannerPosition withOffset: CGPointZero forAdUnitIdentifier: adUnitIdentifier adFormat: DEVICE_SPECIFIC_ADVIEW_AD_FORMAT];
@@ -564,6 +580,11 @@ RCT_EXPORT_METHOD(setMRecPlacement:(NSString *)adUnitIdentifier :(nullable NSStr
564
580
  [self setAdViewPlacement: placement forAdUnitIdentifier: adUnitIdentifier adFormat: MAAdFormat.mrec];
565
581
  }
566
582
 
583
+ RCT_EXPORT_METHOD(setMRecCustomData:(NSString *)adUnitIdentifier :(nullable NSString *)customData)
584
+ {
585
+ [self setAdViewCustomData: customData forAdUnitIdentifier: adUnitIdentifier adFormat: MAAdFormat.mrec];
586
+ }
587
+
567
588
  RCT_EXPORT_METHOD(updateMRecPosition:(NSString *)mrecPosition :(NSString *)adUnitIdentifier)
568
589
  {
569
590
  [self updateAdViewPosition: mrecPosition withOffset: CGPointZero forAdUnitIdentifier: adUnitIdentifier adFormat: MAAdFormat.mrec];
@@ -598,15 +619,10 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(isInterstitialReady:(NSString *)adUnitIde
598
619
  return @([interstitial isReady]);
599
620
  }
600
621
 
601
- RCT_EXPORT_METHOD(showInterstitial:(NSString *)adUnitIdentifier)
602
- {
603
- [self showInterstitialWithPlacement: adUnitIdentifier : nil];
604
- }
605
-
606
- RCT_EXPORT_METHOD(showInterstitialWithPlacement:(NSString *)adUnitIdentifier :(NSString *)placement)
622
+ RCT_EXPORT_METHOD(showInterstitial:(NSString *)adUnitIdentifier :(nullable NSString *)placement :(nullable NSString *)customData)
607
623
  {
608
624
  MAInterstitialAd *interstitial = [self retrieveInterstitialForAdUnitIdentifier: adUnitIdentifier];
609
- [interstitial showAdForPlacement: placement];
625
+ [interstitial showAdForPlacement: placement customData: customData];
610
626
  }
611
627
 
612
628
  RCT_EXPORT_METHOD(setInterstitialExtraParameter:(NSString *)adUnitIdentifier :(NSString *)key :(nullable NSString *)value)
@@ -629,15 +645,10 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(isRewardedAdReady:(NSString *)adUnitIdent
629
645
  return @([rewardedAd isReady]);
630
646
  }
631
647
 
632
- RCT_EXPORT_METHOD(showRewardedAd:(NSString *)adUnitIdentifier)
633
- {
634
- [self showRewardedAdWithPlacement: adUnitIdentifier : nil];
635
- }
636
-
637
- RCT_EXPORT_METHOD(showRewardedAdWithPlacement:(NSString *)adUnitIdentifier :(NSString *)placement)
648
+ RCT_EXPORT_METHOD(showRewardedAd:(NSString *)adUnitIdentifier :(nullable NSString *)placement :(nullable NSString *)customData)
638
649
  {
639
650
  MARewardedAd *rewardedAd = [self retrieveRewardedAdForAdUnitIdentifier: adUnitIdentifier];
640
- [rewardedAd showAdForPlacement: placement];
651
+ [rewardedAd showAdForPlacement: placement customData: customData];
641
652
  }
642
653
 
643
654
  RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSString *)key :(nullable NSString *)value)
@@ -715,7 +726,8 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
715
726
  [self sendReactNativeEventWithName: name body: @{@"adUnitId" : adUnitIdentifier,
716
727
  @"code" : @(error.code),
717
728
  @"message" : error.message,
718
- @"adLoadFailureInfo" : error.adLoadFailureInfo ?: @""}];
729
+ @"adLoadFailureInfo" : error.adLoadFailureInfo ?: @"",
730
+ @"waterfall": [self createAdWaterfallInfo: error.waterfall]}];
719
731
  }
720
732
 
721
733
  - (void)didClickAd:(MAAd *)ad
@@ -834,6 +846,40 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
834
846
  body: [self adInfoForAd: ad]];
835
847
  }
836
848
 
849
+ - (void)didPayRevenueForAd:(MAAd *)ad
850
+ {
851
+ NSString *name;
852
+ MAAdFormat *adFormat = ad.format;
853
+ if ( MAAdFormat.banner == adFormat || MAAdFormat.leader == adFormat )
854
+ {
855
+ name = @"OnBannerAdRevenuePaid";
856
+ }
857
+ else if ( MAAdFormat.mrec == adFormat )
858
+ {
859
+ name = @"OnMRecAdRevenuePaid";
860
+ }
861
+ else if ( MAAdFormat.interstitial == adFormat )
862
+ {
863
+ name = @"OnInterstitialAdRevenuePaid";
864
+ }
865
+ else if ( MAAdFormat.rewarded == adFormat )
866
+ {
867
+ name = @"OnRewardedAdRevenuePaid";
868
+ }
869
+ else
870
+ {
871
+ [self logInvalidAdFormat: adFormat];
872
+ return;
873
+ }
874
+
875
+ NSMutableDictionary *body = [self adInfoForAd: ad].mutableCopy;
876
+ body[@"networkPlacement"] = ad.networkPlacement;
877
+ body[@"revenuePrecision"] = ad.revenuePrecision;
878
+ body[@"countryCode"] = self.sdk.configuration.countryCode;
879
+
880
+ [self sendReactNativeEventWithName: name body: body];
881
+ }
882
+
837
883
  - (void)didCompleteRewardedVideoForAd:(MAAd *)ad
838
884
  {
839
885
  // This event is not forwarded
@@ -926,17 +972,28 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
926
972
  });
927
973
  }
928
974
 
975
+ - (void)setAdViewCustomData:(nullable NSString *)customData forAdUnitIdentifier:(NSString *)adUnitIdentifier adFormat:(MAAdFormat *)adFormat
976
+ {
977
+ dispatch_async(dispatch_get_main_queue(), ^{
978
+
979
+ [self log: @"Setting custom data \"%@\" for \"%@\" with ad unit identifier \"%@\"", customData, adFormat, adUnitIdentifier];
980
+
981
+ MAAdView *adView = [self retrieveAdViewForAdUnitIdentifier: adUnitIdentifier adFormat: adFormat atPosition: @"" withOffset: CGPointZero];
982
+ adView.customData = customData;
983
+ });
984
+ }
985
+
929
986
  - (void)setAdViewWidth:(CGFloat)width forAdUnitIdentifier:(NSString *)adUnitIdentifier adFormat:(MAAdFormat *)adFormat
930
987
  {
931
988
  dispatch_async(dispatch_get_main_queue(), ^{
932
989
  [self log: @"Setting width %f for \"%@\" with ad unit identifier \"%@\"", width, adFormat, adUnitIdentifier];
933
-
990
+
934
991
  CGFloat minWidth = adFormat.size.width;
935
992
  if ( width < minWidth )
936
993
  {
937
994
  [self log: @"The provided with: %f is smaller than the minimum required width: %f for ad format: %@. Please set the width higher than the minimum required.", width, minWidth, adFormat];
938
995
  }
939
-
996
+
940
997
  self.adViewWidths[adUnitIdentifier] = @(width);
941
998
  [self positionAdViewForAdUnitIdentifier: adUnitIdentifier adFormat: adFormat];
942
999
  });
@@ -1040,6 +1097,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1040
1097
 
1041
1098
  MAAdView *view = [self retrieveAdViewForAdUnitIdentifier: adUnitIdentifier adFormat: adFormat];
1042
1099
  view.delegate = nil;
1100
+ view.revenueDelegate = nil;
1043
1101
 
1044
1102
  [view removeFromSuperview];
1045
1103
 
@@ -1051,26 +1109,6 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1051
1109
  });
1052
1110
  }
1053
1111
 
1054
- - (void)logInvalidAdFormat:(MAAdFormat *)adFormat
1055
- {
1056
- [self log: @"invalid ad format: %@, from %@", adFormat, [NSThread callStackSymbols]];
1057
- }
1058
-
1059
- - (void)logUninitializedAccessError:(NSString *)callingMethod
1060
- {
1061
- [self log: @"ERROR: Failed to execute %@() - please ensure the AppLovin MAX React Native module has been initialized by calling 'AppLovinMAX.initialize(...);'!", callingMethod];
1062
- }
1063
-
1064
- - (void)log:(NSString *)format, ...
1065
- {
1066
- va_list valist;
1067
- va_start(valist, format);
1068
- NSString *message = [[NSString alloc] initWithFormat: format arguments: valist];
1069
- va_end(valist);
1070
-
1071
- NSLog(@"[%@] [%@] %@", SDK_TAG, TAG, message);
1072
- }
1073
-
1074
1112
  - (MAInterstitialAd *)retrieveInterstitialForAdUnitIdentifier:(NSString *)adUnitIdentifier
1075
1113
  {
1076
1114
  MAInterstitialAd *result = self.interstitials[adUnitIdentifier];
@@ -1078,6 +1116,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1078
1116
  {
1079
1117
  result = [[MAInterstitialAd alloc] initWithAdUnitIdentifier: adUnitIdentifier sdk: self.sdk];
1080
1118
  result.delegate = self;
1119
+ result.revenueDelegate = self;
1081
1120
 
1082
1121
  self.interstitials[adUnitIdentifier] = result;
1083
1122
  }
@@ -1092,6 +1131,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1092
1131
  {
1093
1132
  result = [MARewardedAd sharedWithAdUnitIdentifier: adUnitIdentifier sdk: self.sdk];
1094
1133
  result.delegate = self;
1134
+ result.revenueDelegate = self;
1095
1135
 
1096
1136
  self.rewardedAds[adUnitIdentifier] = result;
1097
1137
  }
@@ -1111,6 +1151,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1111
1151
  {
1112
1152
  result = [[MAAdView alloc] initWithAdUnitIdentifier: adUnitIdentifier adFormat: adFormat sdk: self.sdk];
1113
1153
  result.delegate = self;
1154
+ result.revenueDelegate = self;
1114
1155
  result.userInteractionEnabled = NO;
1115
1156
  result.translatesAutoresizingMaskIntoConstraints = NO;
1116
1157
 
@@ -1174,7 +1215,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1174
1215
  // Determine ad width
1175
1216
  //
1176
1217
  CGFloat adViewWidth;
1177
-
1218
+
1178
1219
  // Check if publisher has overridden width as points
1179
1220
  if ( isWidthPtsOverridden )
1180
1221
  {
@@ -1190,7 +1231,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1190
1231
  {
1191
1232
  adViewWidth = adFormat.size.width;
1192
1233
  }
1193
-
1234
+
1194
1235
  //
1195
1236
  // Determine ad height
1196
1237
  //
@@ -1318,13 +1359,99 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1318
1359
  [NSLayoutConstraint activateConstraints: constraints];
1319
1360
  }
1320
1361
 
1362
+ - (void)logInvalidAdFormat:(MAAdFormat *)adFormat
1363
+ {
1364
+ [self log: @"invalid ad format: %@, from %@", adFormat, [NSThread callStackSymbols]];
1365
+ }
1366
+
1367
+ - (void)logUninitializedAccessError:(NSString *)callingMethod
1368
+ {
1369
+ [self log: @"ERROR: Failed to execute %@() - please ensure the AppLovin MAX React Native module has been initialized by calling 'AppLovinMAX.initialize(...);'!", callingMethod];
1370
+ }
1371
+
1372
+ - (void)log:(NSString *)format, ...
1373
+ {
1374
+ va_list valist;
1375
+ va_start(valist, format);
1376
+ NSString *message = [[NSString alloc] initWithFormat: format arguments: valist];
1377
+ va_end(valist);
1378
+
1379
+ NSLog(@"[%@] [%@] %@", SDK_TAG, TAG, message);
1380
+ }
1381
+
1382
+ #pragma mark - Ad Info
1383
+
1321
1384
  - (NSDictionary<NSString *, id> *)adInfoForAd:(MAAd *)ad
1322
1385
  {
1323
1386
  return @{@"adUnitId" : ad.adUnitIdentifier,
1324
1387
  @"creativeId" : ad.creativeIdentifier ?: @"",
1325
1388
  @"networkName" : ad.networkName,
1326
1389
  @"placement" : ad.placement ?: @"",
1327
- @"revenue" : @(ad.revenue)};
1390
+ @"revenue" : @(ad.revenue),
1391
+ @"waterfall": [self createAdWaterfallInfo: ad.waterfall],
1392
+ @"dspName" : ad.DSPName ?: @""};
1393
+ }
1394
+
1395
+ #pragma mark - Waterfall Information
1396
+
1397
+ - (NSDictionary<NSString *, id> *)createAdWaterfallInfo:(MAAdWaterfallInfo *)waterfallInfo
1398
+ {
1399
+ NSMutableDictionary<NSString *, NSObject *> *waterfallInfoDict = [NSMutableDictionary dictionary];
1400
+ if ( !waterfallInfo ) return waterfallInfoDict;
1401
+
1402
+ waterfallInfoDict[@"name"] = waterfallInfo.name;
1403
+ waterfallInfoDict[@"testName"] = waterfallInfo.testName;
1404
+
1405
+ NSMutableArray<NSDictionary<NSString *, NSObject *> *> *networkResponsesArray = [NSMutableArray arrayWithCapacity: waterfallInfo.networkResponses.count];
1406
+ for ( MANetworkResponseInfo *response in waterfallInfo.networkResponses )
1407
+ {
1408
+ [networkResponsesArray addObject: [self createNetworkResponseInfo: response]];
1409
+ }
1410
+ waterfallInfoDict[@"networkResponses"] = networkResponsesArray;
1411
+
1412
+ // Convert latency from seconds to milliseconds to match Android.
1413
+ long long latencyMillis = waterfallInfo.latency * 1000;
1414
+ waterfallInfoDict[@"latencyMillis"] = @(latencyMillis);
1415
+
1416
+ return waterfallInfoDict;
1417
+ }
1418
+
1419
+ - (NSDictionary<NSString *, id> *)createNetworkResponseInfo:(MANetworkResponseInfo *)response
1420
+ {
1421
+ NSMutableDictionary<NSString *, NSObject *> *networkResponseDict = [NSMutableDictionary dictionary];
1422
+
1423
+ networkResponseDict[@"adLoadState"] = @(response.adLoadState);
1424
+
1425
+ MAMediatedNetworkInfo *mediatedNetworkInfo = response.mediatedNetwork;
1426
+ if ( mediatedNetworkInfo )
1427
+ {
1428
+ NSMutableDictionary <NSString *, NSObject *> *networkInfoObject = [NSMutableDictionary dictionary];
1429
+ networkInfoObject[@"name"] = mediatedNetworkInfo.name;
1430
+ networkInfoObject[@"adapterClassName"] = mediatedNetworkInfo.adapterClassName;
1431
+ networkInfoObject[@"adapterVersion"] = mediatedNetworkInfo.adapterVersion;
1432
+ networkInfoObject[@"sdkVersion"] = mediatedNetworkInfo.sdkVersion;
1433
+
1434
+ networkResponseDict[@"mediatedNetwork"] = networkInfoObject;
1435
+ }
1436
+
1437
+ networkResponseDict[@"credentials"] = response.credentials;
1438
+
1439
+ MAError *error = response.error;
1440
+ if ( error )
1441
+ {
1442
+ NSMutableDictionary<NSString *, NSObject *> *errorObject = [NSMutableDictionary dictionary];
1443
+ errorObject[@"message"] = error.message;
1444
+ errorObject[@"adLoadFailure"] = error.adLoadFailureInfo;
1445
+ errorObject[@"code"] = @(error.code);
1446
+
1447
+ networkResponseDict[@"error"] = errorObject;
1448
+ }
1449
+
1450
+ // Convert latency from seconds to milliseconds to match Android.
1451
+ long long latencySeconds = response.latency * 1000;
1452
+ networkResponseDict[@"latencyMillis"] = @(latencySeconds);
1453
+
1454
+ return networkResponseDict;
1328
1455
  }
1329
1456
 
1330
1457
  #pragma mark - React Native Event Bridge
@@ -1342,12 +1469,14 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1342
1469
  @"OnMRecAdClickedEvent",
1343
1470
  @"OnMRecAdCollapsedEvent",
1344
1471
  @"OnMRecAdExpandedEvent",
1472
+ @"OnMRecAdRevenuePaid",
1345
1473
 
1346
1474
  @"OnBannerAdLoadedEvent",
1347
1475
  @"OnBannerAdLoadFailedEvent",
1348
1476
  @"OnBannerAdClickedEvent",
1349
1477
  @"OnBannerAdCollapsedEvent",
1350
1478
  @"OnBannerAdExpandedEvent",
1479
+ @"OnBannerAdRevenuePaid",
1351
1480
 
1352
1481
  @"OnInterstitialLoadedEvent",
1353
1482
  @"OnInterstitialLoadFailedEvent",
@@ -1355,6 +1484,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1355
1484
  @"OnInterstitialDisplayedEvent",
1356
1485
  @"OnInterstitialAdFailedToDisplayEvent",
1357
1486
  @"OnInterstitialHiddenEvent",
1487
+ @"OnInterstitialAdRevenuePaid",
1358
1488
 
1359
1489
  @"OnRewardedAdLoadedEvent",
1360
1490
  @"OnRewardedAdLoadFailedEvent",
@@ -1362,7 +1492,8 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1362
1492
  @"OnRewardedAdDisplayedEvent",
1363
1493
  @"OnRewardedAdFailedToDisplayEvent",
1364
1494
  @"OnRewardedAdHiddenEvent",
1365
- @"OnRewardedAdReceivedRewardEvent"];
1495
+ @"OnRewardedAdReceivedRewardEvent",
1496
+ @"OnRewardedAdRevenuePaid"];
1366
1497
  }
1367
1498
 
1368
1499
  - (void)startObserving