react-native-applovin-max 3.0.1 → 3.2.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.
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
@@ -217,13 +217,20 @@ RCT_EXPORT_METHOD(showMediationDebugger)
217
217
  {
218
218
  if ( !_sdk )
219
219
  {
220
- [self log: @"Failed to show mediation debugger - please ensure the AppLovin MAX Unity Plugin has been initialized by calling 'AppLovinMAX.initialize(...);'!"];
220
+ [self logUninitializedAccessError: @"showMediationDebugger"];
221
221
  return;
222
222
  }
223
223
 
224
224
  [self.sdk showMediationDebugger];
225
225
  }
226
226
 
227
+ RCT_EXPORT_METHOD(showConsentDialog:(RCTResponseSenderBlock)callback)
228
+ {
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"];
230
+
231
+ callback(nil);
232
+ }
233
+
227
234
  RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getConsentDialogState)
228
235
  {
229
236
  if ( ![self isInitialized] ) return @(ALConsentDialogStateUnknown);
@@ -342,6 +349,150 @@ RCT_EXPORT_METHOD(setTermsOfServiceUrl:(NSString *)urlString)
342
349
  self.termsOfServiceURLToSet = [NSURL URLWithString: urlString];
343
350
  }
344
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
+
345
496
  #pragma mark - Event Tracking
346
497
 
347
498
  RCT_EXPORT_METHOD(trackEvent:(NSString *)event :(NSDictionary<NSString *, id> *)parameters)
@@ -372,6 +523,11 @@ RCT_EXPORT_METHOD(setBannerPlacement:(NSString *)adUnitIdentifier :(nullable NSS
372
523
  [self setAdViewPlacement: placement forAdUnitIdentifier: adUnitIdentifier adFormat: DEVICE_SPECIFIC_ADVIEW_AD_FORMAT];
373
524
  }
374
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
+
375
531
  RCT_EXPORT_METHOD(updateBannerPosition:(NSString *)adUnitIdentifier :(NSString *)bannerPosition)
376
532
  {
377
533
  [self updateAdViewPosition: bannerPosition withOffset: CGPointZero forAdUnitIdentifier: adUnitIdentifier adFormat: DEVICE_SPECIFIC_ADVIEW_AD_FORMAT];
@@ -424,6 +580,11 @@ RCT_EXPORT_METHOD(setMRecPlacement:(NSString *)adUnitIdentifier :(nullable NSStr
424
580
  [self setAdViewPlacement: placement forAdUnitIdentifier: adUnitIdentifier adFormat: MAAdFormat.mrec];
425
581
  }
426
582
 
583
+ RCT_EXPORT_METHOD(setMRecCustomData:(NSString *)adUnitIdentifier :(nullable NSString *)customData)
584
+ {
585
+ [self setAdViewCustomData: customData forAdUnitIdentifier: adUnitIdentifier adFormat: MAAdFormat.mrec];
586
+ }
587
+
427
588
  RCT_EXPORT_METHOD(updateMRecPosition:(NSString *)mrecPosition :(NSString *)adUnitIdentifier)
428
589
  {
429
590
  [self updateAdViewPosition: mrecPosition withOffset: CGPointZero forAdUnitIdentifier: adUnitIdentifier adFormat: MAAdFormat.mrec];
@@ -458,15 +619,10 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(isInterstitialReady:(NSString *)adUnitIde
458
619
  return @([interstitial isReady]);
459
620
  }
460
621
 
461
- RCT_EXPORT_METHOD(showInterstitial:(NSString *)adUnitIdentifier)
462
- {
463
- [self showInterstitialWithPlacement: adUnitIdentifier : nil];
464
- }
465
-
466
- RCT_EXPORT_METHOD(showInterstitialWithPlacement:(NSString *)adUnitIdentifier :(NSString *)placement)
622
+ RCT_EXPORT_METHOD(showInterstitial:(NSString *)adUnitIdentifier :(nullable NSString *)placement :(nullable NSString *)customData)
467
623
  {
468
624
  MAInterstitialAd *interstitial = [self retrieveInterstitialForAdUnitIdentifier: adUnitIdentifier];
469
- [interstitial showAdForPlacement: placement];
625
+ [interstitial showAdForPlacement: placement customData: customData];
470
626
  }
471
627
 
472
628
  RCT_EXPORT_METHOD(setInterstitialExtraParameter:(NSString *)adUnitIdentifier :(NSString *)key :(nullable NSString *)value)
@@ -489,15 +645,10 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(isRewardedAdReady:(NSString *)adUnitIdent
489
645
  return @([rewardedAd isReady]);
490
646
  }
491
647
 
492
- RCT_EXPORT_METHOD(showRewardedAd:(NSString *)adUnitIdentifier)
493
- {
494
- [self showRewardedAdWithPlacement: adUnitIdentifier : nil];
495
- }
496
-
497
- RCT_EXPORT_METHOD(showRewardedAdWithPlacement:(NSString *)adUnitIdentifier :(NSString *)placement)
648
+ RCT_EXPORT_METHOD(showRewardedAd:(NSString *)adUnitIdentifier :(nullable NSString *)placement :(nullable NSString *)customData)
498
649
  {
499
650
  MARewardedAd *rewardedAd = [self retrieveRewardedAdForAdUnitIdentifier: adUnitIdentifier];
500
- [rewardedAd showAdForPlacement: placement];
651
+ [rewardedAd showAdForPlacement: placement customData: customData];
501
652
  }
502
653
 
503
654
  RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSString *)key :(nullable NSString *)value)
@@ -575,7 +726,8 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
575
726
  [self sendReactNativeEventWithName: name body: @{@"adUnitId" : adUnitIdentifier,
576
727
  @"code" : @(error.code),
577
728
  @"message" : error.message,
578
- @"adLoadFailureInfo" : error.adLoadFailureInfo ?: @""}];
729
+ @"adLoadFailureInfo" : error.adLoadFailureInfo ?: @"",
730
+ @"waterfall": [self createAdWaterfallInfo: error.waterfall]}];
579
731
  }
580
732
 
581
733
  - (void)didClickAd:(MAAd *)ad
@@ -694,6 +846,40 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
694
846
  body: [self adInfoForAd: ad]];
695
847
  }
696
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
+
697
883
  - (void)didCompleteRewardedVideoForAd:(MAAd *)ad
698
884
  {
699
885
  // This event is not forwarded
@@ -786,17 +972,28 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
786
972
  });
787
973
  }
788
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
+
789
986
  - (void)setAdViewWidth:(CGFloat)width forAdUnitIdentifier:(NSString *)adUnitIdentifier adFormat:(MAAdFormat *)adFormat
790
987
  {
791
988
  dispatch_async(dispatch_get_main_queue(), ^{
792
989
  [self log: @"Setting width %f for \"%@\" with ad unit identifier \"%@\"", width, adFormat, adUnitIdentifier];
793
-
990
+
794
991
  CGFloat minWidth = adFormat.size.width;
795
992
  if ( width < minWidth )
796
993
  {
797
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];
798
995
  }
799
-
996
+
800
997
  self.adViewWidths[adUnitIdentifier] = @(width);
801
998
  [self positionAdViewForAdUnitIdentifier: adUnitIdentifier adFormat: adFormat];
802
999
  });
@@ -900,6 +1097,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
900
1097
 
901
1098
  MAAdView *view = [self retrieveAdViewForAdUnitIdentifier: adUnitIdentifier adFormat: adFormat];
902
1099
  view.delegate = nil;
1100
+ view.revenueDelegate = nil;
903
1101
 
904
1102
  [view removeFromSuperview];
905
1103
 
@@ -911,21 +1109,6 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
911
1109
  });
912
1110
  }
913
1111
 
914
- - (void)logInvalidAdFormat:(MAAdFormat *)adFormat
915
- {
916
- [self log: @"invalid ad format: %@, from %@", adFormat, [NSThread callStackSymbols]];
917
- }
918
-
919
- - (void)log:(NSString *)format, ...
920
- {
921
- va_list valist;
922
- va_start(valist, format);
923
- NSString *message = [[NSString alloc] initWithFormat: format arguments: valist];
924
- va_end(valist);
925
-
926
- NSLog(@"[%@] [%@] %@", SDK_TAG, TAG, message);
927
- }
928
-
929
1112
  - (MAInterstitialAd *)retrieveInterstitialForAdUnitIdentifier:(NSString *)adUnitIdentifier
930
1113
  {
931
1114
  MAInterstitialAd *result = self.interstitials[adUnitIdentifier];
@@ -933,6 +1116,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
933
1116
  {
934
1117
  result = [[MAInterstitialAd alloc] initWithAdUnitIdentifier: adUnitIdentifier sdk: self.sdk];
935
1118
  result.delegate = self;
1119
+ result.revenueDelegate = self;
936
1120
 
937
1121
  self.interstitials[adUnitIdentifier] = result;
938
1122
  }
@@ -947,6 +1131,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
947
1131
  {
948
1132
  result = [MARewardedAd sharedWithAdUnitIdentifier: adUnitIdentifier sdk: self.sdk];
949
1133
  result.delegate = self;
1134
+ result.revenueDelegate = self;
950
1135
 
951
1136
  self.rewardedAds[adUnitIdentifier] = result;
952
1137
  }
@@ -966,6 +1151,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
966
1151
  {
967
1152
  result = [[MAAdView alloc] initWithAdUnitIdentifier: adUnitIdentifier adFormat: adFormat sdk: self.sdk];
968
1153
  result.delegate = self;
1154
+ result.revenueDelegate = self;
969
1155
  result.userInteractionEnabled = NO;
970
1156
  result.translatesAutoresizingMaskIntoConstraints = NO;
971
1157
 
@@ -1029,7 +1215,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1029
1215
  // Determine ad width
1030
1216
  //
1031
1217
  CGFloat adViewWidth;
1032
-
1218
+
1033
1219
  // Check if publisher has overridden width as points
1034
1220
  if ( isWidthPtsOverridden )
1035
1221
  {
@@ -1045,7 +1231,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1045
1231
  {
1046
1232
  adViewWidth = adFormat.size.width;
1047
1233
  }
1048
-
1234
+
1049
1235
  //
1050
1236
  // Determine ad height
1051
1237
  //
@@ -1173,13 +1359,98 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1173
1359
  [NSLayoutConstraint activateConstraints: constraints];
1174
1360
  }
1175
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
+
1176
1384
  - (NSDictionary<NSString *, id> *)adInfoForAd:(MAAd *)ad
1177
1385
  {
1178
1386
  return @{@"adUnitId" : ad.adUnitIdentifier,
1179
1387
  @"creativeId" : ad.creativeIdentifier ?: @"",
1180
1388
  @"networkName" : ad.networkName,
1181
1389
  @"placement" : ad.placement ?: @"",
1182
- @"revenue" : @(ad.revenue)};
1390
+ @"revenue" : @(ad.revenue),
1391
+ @"waterfall": [self createAdWaterfallInfo: ad.waterfall]};
1392
+ }
1393
+
1394
+ #pragma mark - Waterfall Information
1395
+
1396
+ - (NSDictionary<NSString *, id> *)createAdWaterfallInfo:(MAAdWaterfallInfo *)waterfallInfo
1397
+ {
1398
+ NSMutableDictionary<NSString *, NSObject *> *waterfallInfoDict = [NSMutableDictionary dictionary];
1399
+ if ( !waterfallInfo ) return waterfallInfoDict;
1400
+
1401
+ waterfallInfoDict[@"name"] = waterfallInfo.name;
1402
+ waterfallInfoDict[@"testName"] = waterfallInfo.testName;
1403
+
1404
+ NSMutableArray<NSDictionary<NSString *, NSObject *> *> *networkResponsesArray = [NSMutableArray arrayWithCapacity: waterfallInfo.networkResponses.count];
1405
+ for ( MANetworkResponseInfo *response in waterfallInfo.networkResponses )
1406
+ {
1407
+ [networkResponsesArray addObject: [self createNetworkResponseInfo: response]];
1408
+ }
1409
+ waterfallInfoDict[@"networkResponses"] = networkResponsesArray;
1410
+
1411
+ // Convert latency from seconds to milliseconds to match Android.
1412
+ long long latencyMillis = waterfallInfo.latency * 1000;
1413
+ waterfallInfoDict[@"latencyMillis"] = @(latencyMillis);
1414
+
1415
+ return waterfallInfoDict;
1416
+ }
1417
+
1418
+ - (NSDictionary<NSString *, id> *)createNetworkResponseInfo:(MANetworkResponseInfo *)response
1419
+ {
1420
+ NSMutableDictionary<NSString *, NSObject *> *networkResponseDict = [NSMutableDictionary dictionary];
1421
+
1422
+ networkResponseDict[@"adLoadState"] = @(response.adLoadState);
1423
+
1424
+ MAMediatedNetworkInfo *mediatedNetworkInfo = response.mediatedNetwork;
1425
+ if ( mediatedNetworkInfo )
1426
+ {
1427
+ NSMutableDictionary <NSString *, NSObject *> *networkInfoObject = [NSMutableDictionary dictionary];
1428
+ networkInfoObject[@"name"] = mediatedNetworkInfo.name;
1429
+ networkInfoObject[@"adapterClassName"] = mediatedNetworkInfo.adapterClassName;
1430
+ networkInfoObject[@"adapterVersion"] = mediatedNetworkInfo.adapterVersion;
1431
+ networkInfoObject[@"sdkVersion"] = mediatedNetworkInfo.sdkVersion;
1432
+
1433
+ networkResponseDict[@"mediatedNetwork"] = networkInfoObject;
1434
+ }
1435
+
1436
+ networkResponseDict[@"credentials"] = response.credentials;
1437
+
1438
+ MAError *error = response.error;
1439
+ if ( error )
1440
+ {
1441
+ NSMutableDictionary<NSString *, NSObject *> *errorObject = [NSMutableDictionary dictionary];
1442
+ errorObject[@"message"] = error.message;
1443
+ errorObject[@"adLoadFailure"] = error.adLoadFailureInfo;
1444
+ errorObject[@"code"] = @(error.code);
1445
+
1446
+ networkResponseDict[@"error"] = errorObject;
1447
+ }
1448
+
1449
+ // Convert latency from seconds to milliseconds to match Android.
1450
+ long long latencySeconds = response.latency * 1000;
1451
+ networkResponseDict[@"latencyMillis"] = @(latencySeconds);
1452
+
1453
+ return networkResponseDict;
1183
1454
  }
1184
1455
 
1185
1456
  #pragma mark - React Native Event Bridge
@@ -1197,12 +1468,14 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1197
1468
  @"OnMRecAdClickedEvent",
1198
1469
  @"OnMRecAdCollapsedEvent",
1199
1470
  @"OnMRecAdExpandedEvent",
1471
+ @"OnMRecAdRevenuePaid",
1200
1472
 
1201
1473
  @"OnBannerAdLoadedEvent",
1202
1474
  @"OnBannerAdLoadFailedEvent",
1203
1475
  @"OnBannerAdClickedEvent",
1204
1476
  @"OnBannerAdCollapsedEvent",
1205
1477
  @"OnBannerAdExpandedEvent",
1478
+ @"OnBannerAdRevenuePaid",
1206
1479
 
1207
1480
  @"OnInterstitialLoadedEvent",
1208
1481
  @"OnInterstitialLoadFailedEvent",
@@ -1210,6 +1483,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1210
1483
  @"OnInterstitialDisplayedEvent",
1211
1484
  @"OnInterstitialAdFailedToDisplayEvent",
1212
1485
  @"OnInterstitialHiddenEvent",
1486
+ @"OnInterstitialAdRevenuePaid",
1213
1487
 
1214
1488
  @"OnRewardedAdLoadedEvent",
1215
1489
  @"OnRewardedAdLoadFailedEvent",
@@ -1217,7 +1491,8 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1217
1491
  @"OnRewardedAdDisplayedEvent",
1218
1492
  @"OnRewardedAdFailedToDisplayEvent",
1219
1493
  @"OnRewardedAdHiddenEvent",
1220
- @"OnRewardedAdReceivedRewardEvent"];
1494
+ @"OnRewardedAdReceivedRewardEvent",
1495
+ @"OnRewardedAdRevenuePaid"];
1221
1496
  }
1222
1497
 
1223
1498
  - (void)startObserving
@@ -25,6 +25,7 @@
25
25
 
26
26
  // Storage for placement and extra parameters if set before the MAAdView is created
27
27
  @property (nonatomic, strong) NSMutableDictionary<NSNumber *, NSString *> *placementRegistry;
28
+ @property (nonatomic, strong) NSMutableDictionary<NSNumber *, NSString *> *customDataRegistry;
28
29
  @property (nonatomic, strong) NSMutableDictionary<NSNumber *, NSString *> *adaptiveBannerEnabledRegistry;
29
30
 
30
31
  @end
@@ -46,6 +47,7 @@ RCT_EXPORT_MODULE(AppLovinMAXAdView)
46
47
  self.adUnitIdRegistry = [NSMutableDictionary dictionary];
47
48
  self.adFormatRegistry = [NSMutableDictionary dictionary];
48
49
  self.placementRegistry = [NSMutableDictionary dictionary];
50
+ self.customDataRegistry = [NSMutableDictionary dictionary];
49
51
  self.adaptiveBannerEnabledRegistry = [NSMutableDictionary dictionary];
50
52
  }
51
53
  return self;
@@ -82,6 +84,31 @@ RCT_EXPORT_METHOD(setPlacement:(nonnull NSNumber *)viewTag toPlacement:(NSString
82
84
  }];
83
85
  }
84
86
 
87
+ // NOTE: `nonnull` must be annotated here for this RN export to work at runtime
88
+ RCT_EXPORT_METHOD(setCustomData:(nonnull NSNumber *)viewTag toCustomData:(NSString *)customData)
89
+ {
90
+ [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
91
+
92
+ // NOTE: iOS caches the native view via `viewTag` when you remove it from screen (unlike Android)
93
+ UIView *view = viewRegistry[viewTag];
94
+ if ( !view )
95
+ {
96
+ RCTLogError(@"Cannot find UIView with tag %@", viewTag);
97
+ return;
98
+ }
99
+
100
+ MAAdView *adView = [self adViewFromContainerView: view];
101
+ if ( adView )
102
+ {
103
+ adView.customData = customData;
104
+ }
105
+ else
106
+ {
107
+ self.customDataRegistry[viewTag] = customData;
108
+ }
109
+ }];
110
+ }
111
+
85
112
  // NOTE: `nonnull` must be annotated here for this RN export to work at runtime
86
113
  RCT_EXPORT_METHOD(setAdaptiveBannerEnabled:(nonnull NSNumber *)viewTag toEnabled:(NSString *)enabledStr)
87
114
  {
@@ -180,6 +207,7 @@ RCT_EXPORT_METHOD(setAdFormat:(nonnull NSNumber *)viewTag toAdFormat:(NSString *
180
207
  adView = [[MAAdView alloc] initWithAdUnitIdentifier: adUnitIdentifier adFormat: adFormat sdk: AppLovinMAX.shared.sdk];
181
208
  adView.frame = (CGRect) { CGPointZero, adFormat.size };
182
209
  adView.delegate = AppLovinMAX.shared; // Go through core class for callback forwarding to React Native layer
210
+ adView.revenueDelegate = AppLovinMAX.shared;
183
211
 
184
212
  NSString *placement = self.placementRegistry[viewTag];
185
213
  if ( placement )
@@ -188,6 +216,13 @@ RCT_EXPORT_METHOD(setAdFormat:(nonnull NSNumber *)viewTag toAdFormat:(NSString *
188
216
  adView.placement = placement;
189
217
  }
190
218
 
219
+ NSString *customData = self.customDataRegistry[viewTag];
220
+ if ( customData )
221
+ {
222
+ [self.customDataRegistry removeObjectForKey: viewTag];
223
+ adView.customData = customData;
224
+ }
225
+
191
226
  NSString *adaptiveBannerEnabledStr = self.adaptiveBannerEnabledRegistry[viewTag];
192
227
  if ( [adaptiveBannerEnabledStr al_isValidString] )
193
228
  {
package/ios/Podfile CHANGED
@@ -35,6 +35,6 @@ target 'AppLovinMAX' do
35
35
  pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
36
36
  pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
37
37
 
38
- pod 'AppLovinSDK', '11.3.1'
38
+ pod 'AppLovinSDK', '11.4.2'
39
39
 
40
40
  end
package/ios/Podfile.lock CHANGED
@@ -1,5 +1,5 @@
1
1
  PODS:
2
- - AppLovinSDK (11.3.1)
2
+ - AppLovinSDK (11.4.2)
3
3
  - boost-for-react-native (1.63.0)
4
4
  - DoubleConversion (1.1.6)
5
5
  - FBLazyVector (0.63.4)
@@ -249,7 +249,7 @@ PODS:
249
249
  - Yoga (1.14.0)
250
250
 
251
251
  DEPENDENCIES:
252
- - AppLovinSDK (= 11.3.1)
252
+ - AppLovinSDK (= 11.4.2)
253
253
  - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
254
254
  - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
255
255
  - FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`)
@@ -339,7 +339,7 @@ EXTERNAL SOURCES:
339
339
  :path: "../node_modules/react-native/ReactCommon/yoga"
340
340
 
341
341
  SPEC CHECKSUMS:
342
- AppLovinSDK: 7965663198de61735b77106702ca8e320299e53c
342
+ AppLovinSDK: 119a0b2a743f9d9c6002c58776b1013778a65084
343
343
  boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
344
344
  DoubleConversion: cde416483dac037923206447da6e1454df403714
345
345
  FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e
@@ -368,6 +368,6 @@ SPEC CHECKSUMS:
368
368
  ReactCommon: 73d79c7039f473b76db6ff7c6b159c478acbbb3b
369
369
  Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6
370
370
 
371
- PODFILE CHECKSUM: 6b63830cde67b1a13c9afbe42cadc7bfc28c9d05
371
+ PODFILE CHECKSUM: 485c4fe7a35ea71547f789315321ae261127772e
372
372
 
373
373
  COCOAPODS: 1.11.2
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-native-applovin-max",
3
3
  "author": "AppLovin Corporation",
4
- "version": "3.0.1",
4
+ "version": "3.2.0",
5
5
  "description": "AppLovin MAX React Native Plugin for Android and iOS",
6
6
  "homepage": "https://github.com/AppLovin/AppLovin-MAX-React-Native",
7
7
  "license": "MIT",
@@ -11,10 +11,10 @@ Pod::Spec.new do |s|
11
11
  s.authors = package["author"]
12
12
 
13
13
  s.platforms = { :ios => "10.0" }
14
- s.source = { :git => "https://github.com/AppLovin/AppLovin-MAX-React-Native.git", :tag => "release_3_0_1" }
14
+ s.source = { :git => "https://github.com/AppLovin/AppLovin-MAX-React-Native.git", :tag => "release_3_2_0" }
15
15
 
16
16
  s.source_files = "ios/AppLovinMAX*.{h,m}"
17
17
 
18
18
  s.dependency "React"
19
- s.dependency "AppLovinSDK", "11.3.1"
19
+ s.dependency "AppLovinSDK", "11.4.2"
20
20
  end