react-native-applovin-max 6.0.2 → 6.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.
package/android/.project CHANGED
@@ -1,10 +1,15 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <projectDescription>
3
- <name>android_</name>
3
+ <name>android</name>
4
4
  <comment>Project android_ created by Buildship.</comment>
5
5
  <projects>
6
6
  </projects>
7
7
  <buildSpec>
8
+ <buildCommand>
9
+ <name>org.eclipse.jdt.core.javabuilder</name>
10
+ <arguments>
11
+ </arguments>
12
+ </buildCommand>
8
13
  <buildCommand>
9
14
  <name>org.eclipse.buildship.core.gradleprojectbuilder</name>
10
15
  <arguments>
@@ -12,6 +17,7 @@
12
17
  </buildCommand>
13
18
  </buildSpec>
14
19
  <natures>
20
+ <nature>org.eclipse.jdt.core.javanature</nature>
15
21
  <nature>org.eclipse.buildship.core.gradleprojectnature</nature>
16
22
  </natures>
17
23
  </projectDescription>
@@ -1,11 +1,11 @@
1
- arguments=
1
+ arguments=--init-script /var/folders/7v/xx4_6n150w136j9cfrzqdc2w0000gq/T/d146c9752a26f79b52047fb6dc6ed385d064e120494f96f08ca63a317c41f94c.gradle --init-script /var/folders/7v/xx4_6n150w136j9cfrzqdc2w0000gq/T/52cde0cfcf3e28b8b7510e992210d9614505e0911af0c190bd590d7158574963.gradle
2
2
  auto.sync=false
3
3
  build.scans.enabled=false
4
- connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(6.0))
4
+ connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
5
5
  connection.project.dir=
6
6
  eclipse.preferences.version=1
7
7
  gradle.user.home=
8
- java.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home
8
+ java.home=/Users/hiroshi.watanabe/Library/Java/JavaVirtualMachines/corretto-11.0.21/Contents/Home
9
9
  jvm.arguments=
10
10
  offline.mode=false
11
11
  override.workspace.settings=true
@@ -35,8 +35,8 @@ android {
35
35
  defaultConfig {
36
36
  minSdkVersion 16
37
37
  targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
38
- versionCode 6000200
39
- versionName "6.0.2"
38
+ versionCode 6010100
39
+ versionName "6.1.1"
40
40
  }
41
41
 
42
42
  flavorDimensions("default")
@@ -140,5 +140,5 @@ dependencies {
140
140
  // noinspection GradleDynamicVersion
141
141
  api 'com.facebook.react:react-native:+'
142
142
 
143
- implementation 'com.applovin:applovin-sdk:12.0.0'
143
+ implementation 'com.applovin:applovin-sdk:12.1.0'
144
144
  }
@@ -456,7 +456,7 @@ public class GoogleMediationAdapter
456
456
  else
457
457
  {
458
458
  log( "App open ad failed to show: " + placementId );
459
- listener.onAppOpenAdLoadFailed( new MaxAdapterError( -4205, "Ad display failed", 0, "App open ad not ready" ) );
459
+ listener.onAppOpenAdDisplayFailed( new MaxAdapterError( -4205, "Ad display failed", 0, "App open ad not ready" ) );
460
460
  }
461
461
  }
462
462
 
@@ -1327,7 +1327,7 @@ public class GoogleMediationAdapter
1327
1327
  if ( TextUtils.isEmpty( nativeAd.getHeadline() ) )
1328
1328
  {
1329
1329
  log( "Native " + adFormat.getLabel() + " ad failed to load: Google native ad is missing one or more required assets" );
1330
- listener.onAdViewAdLoadFailed( MaxAdapterError.INVALID_CONFIGURATION );
1330
+ listener.onAdViewAdLoadFailed( new MaxAdapterError( -5400, "Missing Native Ad Assets" ) );
1331
1331
 
1332
1332
  nativeAd.destroy();
1333
1333
 
@@ -7,6 +7,7 @@ import android.content.pm.PackageManager;
7
7
  import android.graphics.Color;
8
8
  import android.graphics.Point;
9
9
  import android.graphics.Rect;
10
+ import android.net.Uri;
10
11
  import android.os.Bundle;
11
12
  import android.text.TextUtils;
12
13
  import android.util.Log;
@@ -41,6 +42,7 @@ import com.applovin.sdk.AppLovinMediationProvider;
41
42
  import com.applovin.sdk.AppLovinPrivacySettings;
42
43
  import com.applovin.sdk.AppLovinSdk;
43
44
  import com.applovin.sdk.AppLovinSdkConfiguration;
45
+ import com.applovin.sdk.AppLovinSdkConfiguration.ConsentFlowUserGeography;
44
46
  import com.applovin.sdk.AppLovinSdkSettings;
45
47
  import com.applovin.sdk.AppLovinSdkUtils;
46
48
  import com.facebook.react.bridge.Arguments;
@@ -79,6 +81,10 @@ public class AppLovinMAXModule
79
81
  private static final String SDK_TAG = "AppLovinSdk";
80
82
  private static final String TAG = "AppLovinMAXModule";
81
83
 
84
+ private static final String USER_GEOGRAPHY_GDPR = "G";
85
+ private static final String USER_GEOGRAPHY_OTHER = "O";
86
+ private static final String USER_GEOGRAPHY_UNKNOWN = "U";
87
+
82
88
  private static final String ON_BANNER_AD_LOADED_EVENT = "OnBannerAdLoadedEvent";
83
89
  private static final String ON_BANNER_AD_LOAD_FAILED_EVENT = "OnBannerAdLoadFailedEvent";
84
90
  private static final String ON_BANNER_AD_CLICKED_EVENT = "OnBannerAdClickedEvent";
@@ -143,13 +149,20 @@ public class AppLovinMAXModule
143
149
  private int lastRotation;
144
150
 
145
151
  // Store these values if pub attempts to set it before initializing
152
+ private List<String> initializationAdUnitIdsToSet;
146
153
  private String userIdToSet;
154
+ private Boolean mutedToSet;
147
155
  private List<String> testDeviceAdvertisingIdsToSet;
148
156
  private Boolean verboseLoggingToSet;
149
157
  private Boolean creativeDebuggerEnabledToSet;
150
158
  private Boolean locationCollectionEnabledToSet;
151
159
  private final Map<String, String> extraParametersToSet = new HashMap<>( 8 );
152
160
 
161
+ private Boolean termsAndPrivacyPolicyFlowEnabledToSet;
162
+ private Uri privacyPolicyURLToSet;
163
+ private Uri termsOfServiceURLToSet;
164
+ private String debugUserGeographyToSet;
165
+
153
166
  private Integer targetingYearOfBirthToSet;
154
167
  private String targetingGenderToSet;
155
168
  private Integer targetingMaximumAdContentRatingToSet;
@@ -286,46 +299,88 @@ public class AppLovinMAXModule
286
299
  }
287
300
  }
288
301
 
289
- // Initialize SDK
290
- sdk = AppLovinSdk.getInstance( sdkKeyToUse, new AppLovinSdkSettings( getReactApplicationContext() ), context );
291
- sdk.setPluginVersion( "React-Native-" + pluginVersion );
292
- sdk.setMediationProvider( AppLovinMediationProvider.MAX );
302
+ AppLovinSdkSettings settings = new AppLovinSdkSettings( getReactApplicationContext() );
293
303
 
294
- // Set user id if needed
295
- if ( !TextUtils.isEmpty( userIdToSet ) )
304
+ // Selective init
305
+ if ( initializationAdUnitIdsToSet != null )
296
306
  {
297
- sdk.setUserIdentifier( userIdToSet );
298
- userIdToSet = null;
307
+ settings.setInitializationAdUnitIds( initializationAdUnitIdsToSet );
308
+ initializationAdUnitIdsToSet = null;
309
+ }
310
+
311
+ if ( termsAndPrivacyPolicyFlowEnabledToSet != null )
312
+ {
313
+ settings.getTermsAndPrivacyPolicyFlowSettings().setEnabled( termsAndPrivacyPolicyFlowEnabledToSet );
314
+ termsAndPrivacyPolicyFlowEnabledToSet = null;
315
+ }
316
+
317
+ if ( privacyPolicyURLToSet != null )
318
+ {
319
+ settings.getTermsAndPrivacyPolicyFlowSettings().setPrivacyPolicyUri( privacyPolicyURLToSet );
320
+ privacyPolicyURLToSet = null;
321
+ }
322
+
323
+ if ( termsOfServiceURLToSet != null )
324
+ {
325
+ settings.getTermsAndPrivacyPolicyFlowSettings().setTermsOfServiceUri( termsOfServiceURLToSet );
326
+ termsOfServiceURLToSet = null;
327
+ }
328
+
329
+ if ( AppLovinSdkUtils.isValidString( debugUserGeographyToSet ) )
330
+ {
331
+ settings.getTermsAndPrivacyPolicyFlowSettings().setDebugUserGeography( getAppLovinConsentFlowUserGeography( debugUserGeographyToSet ) );
332
+ debugUserGeographyToSet = null;
333
+ }
334
+
335
+ // Set muted if needed
336
+ if ( mutedToSet != null )
337
+ {
338
+ settings.setMuted( mutedToSet );
339
+ mutedToSet = null;
299
340
  }
300
341
 
301
342
  // Set test device ids if needed
302
343
  if ( testDeviceAdvertisingIdsToSet != null )
303
344
  {
304
- sdk.getSettings().setTestDeviceAdvertisingIds( testDeviceAdvertisingIdsToSet );
345
+ settings.setTestDeviceAdvertisingIds( testDeviceAdvertisingIdsToSet );
305
346
  testDeviceAdvertisingIdsToSet = null;
306
347
  }
307
348
 
308
349
  // Set verbose logging state if needed
309
350
  if ( verboseLoggingToSet != null )
310
351
  {
311
- sdk.getSettings().setVerboseLogging( verboseLoggingToSet );
352
+ settings.setVerboseLogging( verboseLoggingToSet );
312
353
  verboseLoggingToSet = null;
313
354
  }
314
355
 
315
356
  // Set creative debugger enabled if needed.
316
357
  if ( creativeDebuggerEnabledToSet != null )
317
358
  {
318
- sdk.getSettings().setCreativeDebuggerEnabled( creativeDebuggerEnabledToSet );
359
+ settings.setCreativeDebuggerEnabled( creativeDebuggerEnabledToSet );
319
360
  creativeDebuggerEnabledToSet = null;
320
361
  }
321
362
 
322
363
  // Set location collection enabled if needed
323
364
  if ( locationCollectionEnabledToSet != null )
324
365
  {
325
- sdk.getSettings().setLocationCollectionEnabled( locationCollectionEnabledToSet );
366
+ settings.setLocationCollectionEnabled( locationCollectionEnabledToSet );
326
367
  locationCollectionEnabledToSet = null;
327
368
  }
328
369
 
370
+ setPendingExtraParametersIfNeeded( settings );
371
+
372
+ // Initialize SDK
373
+ sdk = AppLovinSdk.getInstance( sdkKeyToUse, settings, context );
374
+ sdk.setPluginVersion( "React-Native-" + pluginVersion );
375
+ sdk.setMediationProvider( AppLovinMediationProvider.MAX );
376
+
377
+ // Set user id if needed
378
+ if ( AppLovinSdkUtils.isValidString( userIdToSet ) )
379
+ {
380
+ sdk.setUserIdentifier( userIdToSet );
381
+ userIdToSet = null;
382
+ }
383
+
329
384
  if ( targetingYearOfBirthToSet != null )
330
385
  {
331
386
  sdk.getTargetingData().setYearOfBirth( targetingYearOfBirthToSet <= 0 ? null : targetingYearOfBirthToSet );
@@ -368,8 +423,6 @@ public class AppLovinMAXModule
368
423
  targetingInterestsToSet = null;
369
424
  }
370
425
 
371
- setPendingExtraParametersIfNeeded( sdk.getSettings() );
372
-
373
426
  sdk.initializeSdk( new AppLovinSdk.SdkInitializationListener()
374
427
  {
375
428
  @Override
@@ -404,6 +457,8 @@ public class AppLovinMAXModule
404
457
 
405
458
  WritableMap sdkConfiguration = Arguments.createMap();
406
459
  sdkConfiguration.putString( "countryCode", configuration.getCountryCode() );
460
+ sdkConfiguration.putString( "consentFlowUserGeography", getRawAppLovinConsentFlowUserGeography( configuration.getConsentFlowUserGeography() ) );
461
+ sdkConfiguration.putBoolean( "isTestModeEnabled", configuration.isTestModeEnabled() );
407
462
  promise.resolve( sdkConfiguration );
408
463
  }
409
464
  } );
@@ -484,9 +539,15 @@ public class AppLovinMAXModule
484
539
  @ReactMethod
485
540
  public void setMuted(final boolean muted)
486
541
  {
487
- if ( !isPluginInitialized ) return;
488
-
489
- sdk.getSettings().setMuted( muted );
542
+ if ( isPluginInitialized )
543
+ {
544
+ sdk.getSettings().setMuted( muted );
545
+ mutedToSet = null;
546
+ }
547
+ else
548
+ {
549
+ mutedToSet = muted;
550
+ }
490
551
  }
491
552
 
492
553
  @ReactMethod
@@ -566,14 +627,46 @@ public class AppLovinMAXModule
566
627
  }
567
628
  }
568
629
 
630
+ @ReactMethod
631
+ public void setInitializationAdUnitIds(final ReadableArray rawAdUnitIds)
632
+ {
633
+ initializationAdUnitIdsToSet = new ArrayList<>( rawAdUnitIds.size() );
634
+
635
+ // Convert to String List
636
+ for ( Object adUnitId : rawAdUnitIds.toArrayList() )
637
+ {
638
+ initializationAdUnitIdsToSet.add( (String) adUnitId );
639
+ }
640
+ }
641
+
642
+ // MAX Terms and Privacy Policy Flow
643
+
569
644
  @ReactMethod
570
645
  public void setConsentFlowEnabled(final boolean enabled) { }
571
646
 
572
647
  @ReactMethod
573
- public void setPrivacyPolicyUrl(final String urlString) { }
648
+ public void setTermsAndPrivacyPolicyFlowEnabled(final boolean enabled)
649
+ {
650
+ termsAndPrivacyPolicyFlowEnabledToSet = enabled;
651
+ }
652
+
653
+ @ReactMethod
654
+ public void setPrivacyPolicyUrl(final String urlString)
655
+ {
656
+ privacyPolicyURLToSet = Uri.parse( urlString );
657
+ }
574
658
 
575
659
  @ReactMethod
576
- public void setTermsOfServiceUrl(final String urlString) { }
660
+ public void setTermsOfServiceUrl(final String urlString)
661
+ {
662
+ termsOfServiceURLToSet = Uri.parse( urlString );
663
+ }
664
+
665
+ @ReactMethod
666
+ public void setConsentFlowDebugUserGeography(final String userGeography)
667
+ {
668
+ debugUserGeographyToSet = userGeography;
669
+ }
577
670
 
578
671
  // Data Passing
579
672
 
@@ -1406,7 +1499,7 @@ public class AppLovinMAXModule
1406
1499
  name = ( MaxAdFormat.MREC == adFormat ) ? ON_MREC_AD_LOADED_EVENT : ON_BANNER_AD_LOADED_EVENT;
1407
1500
 
1408
1501
  String adViewPosition = mAdViewPositions.get( ad.getAdUnitId() );
1409
- if ( !TextUtils.isEmpty( adViewPosition ) )
1502
+ if ( AppLovinSdkUtils.isValidString( adViewPosition ) )
1410
1503
  {
1411
1504
  // Only position ad if not native UI component
1412
1505
  positionAdView( ad );
@@ -2421,18 +2514,46 @@ public class AppLovinMAXModule
2421
2514
  return AppLovinAdContentRating.NONE;
2422
2515
  }
2423
2516
 
2517
+ private static ConsentFlowUserGeography getAppLovinConsentFlowUserGeography(final String userGeography)
2518
+ {
2519
+ if ( USER_GEOGRAPHY_GDPR.equalsIgnoreCase( userGeography ) )
2520
+ {
2521
+ return ConsentFlowUserGeography.GDPR;
2522
+ }
2523
+ else if ( USER_GEOGRAPHY_OTHER.equalsIgnoreCase( userGeography ) )
2524
+ {
2525
+ return ConsentFlowUserGeography.OTHER;
2526
+ }
2527
+
2528
+ return ConsentFlowUserGeography.UNKNOWN;
2529
+ }
2530
+
2531
+ private static String getRawAppLovinConsentFlowUserGeography(final ConsentFlowUserGeography userGeography)
2532
+ {
2533
+ if ( ConsentFlowUserGeography.GDPR == userGeography )
2534
+ {
2535
+ return USER_GEOGRAPHY_GDPR;
2536
+ }
2537
+ else if ( ConsentFlowUserGeography.OTHER == userGeography )
2538
+ {
2539
+ return USER_GEOGRAPHY_OTHER;
2540
+ }
2541
+
2542
+ return USER_GEOGRAPHY_UNKNOWN;
2543
+ }
2544
+
2424
2545
  // AD INFO
2425
2546
 
2426
2547
  public WritableMap getAdInfo(final MaxAd ad)
2427
2548
  {
2428
2549
  WritableMap adInfo = Arguments.createMap();
2429
2550
  adInfo.putString( "adUnitId", ad.getAdUnitId() );
2430
- adInfo.putString( "creativeId", !TextUtils.isEmpty( ad.getCreativeId() ) ? ad.getCreativeId() : "" );
2551
+ adInfo.putString( "creativeId", AppLovinSdkUtils.isValidString( ad.getCreativeId() ) ? ad.getCreativeId() : "" );
2431
2552
  adInfo.putString( "networkName", ad.getNetworkName() );
2432
- adInfo.putString( "placement", !TextUtils.isEmpty( ad.getPlacement() ) ? ad.getPlacement() : "" );
2553
+ adInfo.putString( "placement", AppLovinSdkUtils.isValidString( ad.getPlacement() ) ? ad.getPlacement() : "" );
2433
2554
  adInfo.putDouble( "revenue", ad.getRevenue() );
2434
2555
  adInfo.putMap( "waterfall", createAdWaterfallInfo( ad.getWaterfall() ) );
2435
- adInfo.putString( "dspName", !TextUtils.isEmpty( ad.getDspName() ) ? ad.getDspName() : "" );
2556
+ adInfo.putString( "dspName", AppLovinSdkUtils.isValidString( ad.getDspName() ) ? ad.getDspName() : "" );
2436
2557
 
2437
2558
  return adInfo;
2438
2559
  }
@@ -1,6 +1,8 @@
1
1
  package com.applovin.reactnative;
2
2
 
3
3
  import android.content.Context;
4
+ import android.os.Handler;
5
+ import android.os.Looper;
4
6
  import android.text.TextUtils;
5
7
  import android.view.View;
6
8
  import android.view.ViewGroup;
@@ -29,8 +31,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
29
31
 
30
32
  import androidx.annotation.Nullable;
31
33
 
32
- import static com.applovin.sdk.AppLovinSdkUtils.runOnUiThreadDelayed;
33
-
34
34
  public class AppLovinMAXNativeAdView
35
35
  extends ReactViewGroup
36
36
  implements MaxAdRevenueListener, View.OnLayoutChangeListener, ViewGroup.OnHierarchyChangeListener
@@ -42,12 +42,15 @@ public class AppLovinMAXNativeAdView
42
42
  private static final int CALL_TO_ACTION_VIEW_TAG = 5;
43
43
  private static final int ADVERTISER_VIEW_TAG = 8;
44
44
 
45
- private final ReactContext reactContext;
45
+ private final ReactContext reactContext;
46
46
  @Nullable
47
- private MaxNativeAdLoader adLoader;
47
+ private MaxNativeAdLoader adLoader;
48
48
  @Nullable
49
- private MaxAd nativeAd;
50
- private final AtomicBoolean isLoading = new AtomicBoolean(); // Guard against repeated ad loads
49
+ private MaxAd nativeAd;
50
+ private final AtomicBoolean isLoading = new AtomicBoolean(); // Guard against repeated ad loads
51
+ private final AtomicBoolean isAdUnitIdSet = new AtomicBoolean();
52
+ private final Handler renderNativeAdHandler = new Handler( Looper.getMainLooper() );
53
+ private final RenderNativeAdTask renderNativeAdTask = new RenderNativeAdTask( this );
51
54
 
52
55
  @Nullable
53
56
  private View mediaView;
@@ -91,8 +94,7 @@ public class AppLovinMAXNativeAdView
91
94
 
92
95
  adUnitId = value;
93
96
 
94
- // Explicitly invoke ad load now that Ad Unit ID is set, but do so after 0.25s to allow other props to set
95
- postDelayed( this::loadAd, 250 );
97
+ isAdUnitIdSet.set( true );
96
98
  }
97
99
 
98
100
  public void setPlacement(@Nullable final String value)
@@ -197,25 +199,7 @@ public class AppLovinMAXNativeAdView
197
199
  // Notify `AppLovinNativeAdView.js`
198
200
  sendAdLoadedReactNativeEventForAd( ad.getNativeAd() );
199
201
 
200
- // After notifying the RN layer - have slight delay to let views bind to this layer in `clickableViews` before registering
201
- runOnUiThreadDelayed( () -> {
202
-
203
- // Loader can be null when the user hides before the properties are fully set
204
- if ( adLoader != null )
205
- {
206
- adLoader.a( clickableViews, AppLovinMAXNativeAdView.this, ad );
207
- adLoader.b( ad );
208
- }
209
-
210
- // Reassure the size of `mediaView` and its children for the networks, such as
211
- // LINE, where the actual ad contents are loaded after `mediaView` is sized.
212
- if ( mediaView != null && mediaView.getParent() != null )
213
- {
214
- sizeToFit( mediaView, (View) mediaView.getParent() );
215
- }
216
-
217
- isLoading.set( false );
218
- }, 500L );
202
+ isLoading.set( false );
219
203
  }
220
204
 
221
205
  @Override
@@ -421,6 +405,48 @@ public class AppLovinMAXNativeAdView
421
405
  }
422
406
  }
423
407
 
408
+ static class RenderNativeAdTask
409
+ implements Runnable
410
+ {
411
+ private AppLovinMAXNativeAdView nativeAdView;
412
+
413
+ RenderNativeAdTask(AppLovinMAXNativeAdView nativeAdView) { this.nativeAdView = nativeAdView; }
414
+
415
+ @Override
416
+ public void run()
417
+ {
418
+ if ( nativeAdView.adLoader == null ) return;
419
+
420
+ nativeAdView.adLoader.a( nativeAdView.clickableViews, nativeAdView, nativeAdView.nativeAd );
421
+ nativeAdView.adLoader.b( nativeAdView.nativeAd );
422
+
423
+ // LINE needs to be sized a while after its mediaView is attached to the React Native
424
+ if ( nativeAdView.mediaView != null && nativeAdView.mediaView.getParent() != null )
425
+ {
426
+ nativeAdView.renderNativeAdHandler.postDelayed( () -> sizeToFit( nativeAdView.mediaView, (View) nativeAdView.mediaView.getParent() ), 500 );
427
+ }
428
+ }
429
+ }
430
+
431
+ /**
432
+ * Invoked via ViewManager.onAfterUpdateTransaction():
433
+ * 1. after all the JavaScript properties are set when mounting NativeAdView
434
+ * 2. every time one of the asset views is mounted, following the 1st event
435
+ */
436
+ public void onSetProps()
437
+ {
438
+ if ( isAdUnitIdSet.compareAndSet( true, false ) )
439
+ {
440
+ loadAd();
441
+ }
442
+ else
443
+ {
444
+ // Renders the ad only after the last asset view is set
445
+ renderNativeAdHandler.removeCallbacksAndMessages( null );
446
+ renderNativeAdHandler.postDelayed( renderNativeAdTask, 1 );
447
+ }
448
+ }
449
+
424
450
  @Override
425
451
  public void onLayoutChange(View view, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom)
426
452
  {
@@ -148,6 +148,14 @@ public class AppLovinMAXNativeAdViewManager
148
148
  view.setMediaView( value );
149
149
  }
150
150
 
151
+ @Override
152
+ public void onAfterUpdateTransaction(final AppLovinMAXNativeAdView view)
153
+ {
154
+ super.onAfterUpdateTransaction( view );
155
+
156
+ view.onSetProps();
157
+ }
158
+
151
159
  @Override
152
160
  public void onDropViewInstance(@NonNull final AppLovinMAXNativeAdView view)
153
161
  {
package/ios/AppLovinMAX.m CHANGED
@@ -37,7 +37,9 @@
37
37
  @property (nonatomic, strong) ALSdkConfiguration *sdkConfiguration;
38
38
 
39
39
  // Store these values if pub attempts to set it before initializing
40
+ @property (nonatomic, strong, nullable) NSArray<NSString *> *initializationAdUnitIdentifiersToSet;
40
41
  @property (nonatomic, copy, nullable) NSString *userIdentifierToSet;
42
+ @property (nonatomic, strong, nullable) NSNumber *mutedToSet;
41
43
  @property (nonatomic, strong, nullable) NSArray<NSString *> *testDeviceIdentifiersToSet;
42
44
  @property (nonatomic, strong, nullable) NSNumber *verboseLoggingToSet;
43
45
  @property (nonatomic, strong, nullable) NSNumber *creativeDebuggerEnabledToSet;
@@ -45,8 +47,10 @@
45
47
  @property (nonatomic, strong) NSMutableDictionary<NSString *, NSString *> *extraParametersToSet;
46
48
 
47
49
  @property (nonatomic, strong, nullable) NSNumber *consentFlowEnabledToSet;
50
+ @property (nonatomic, strong, nullable) NSNumber *termsAndPrivacyPolicyFlowEnabledToSet;
48
51
  @property (nonatomic, strong, nullable) NSURL *privacyPolicyURLToSet;
49
52
  @property (nonatomic, strong, nullable) NSURL *termsOfServiceURLToSet;
53
+ @property (nonatomic, copy, nullable) NSString *debugUserGeographyToSet;
50
54
 
51
55
  @property (nonatomic, strong, nullable) NSNumber *targetingYearOfBirthToSet;
52
56
  @property (nonatomic, copy, nullable) NSString *targetingGenderToSet;
@@ -82,6 +86,16 @@
82
86
  static NSString *const SDK_TAG = @"AppLovinSdk";
83
87
  static NSString *const TAG = @"AppLovinMAX";
84
88
 
89
+ static NSString *const USER_GEOGRAPHY_GDPR = @"G";
90
+ static NSString *const USER_GEOGRAPHY_OTHER = @"O";
91
+ static NSString *const USER_GEOGRAPHY_UNKNOWN = @"U";
92
+
93
+ static NSString *const APP_TRACKING_STATUS_NOTDETERMINED = @"N";
94
+ static NSString *const APP_TRACKING_STATUS_RESTRICTED = @"R";
95
+ static NSString *const APP_TRACKING_STATUS_DENIED = @"D";
96
+ static NSString *const APP_TRACKING_STATUS_AUTHORIZED = @"A";
97
+ static NSString *const APP_TRACKING_STATUS_UNAVAILABLE = @"U";
98
+
85
99
  static NSString *const ON_BANNER_AD_LOADED_EVENT = @"OnBannerAdLoadedEvent";
86
100
  static NSString *const ON_BANNER_AD_LOAD_FAILED_EVENT = @"OnBannerAdLoadFailedEvent";
87
101
  static NSString *const ON_BANNER_AD_CLICKED_EVENT = @"OnBannerAdClickedEvent";
@@ -212,54 +226,107 @@ RCT_EXPORT_METHOD(initialize:(NSString *)pluginVersion :(NSString *)sdkKey :(RCT
212
226
  }
213
227
 
214
228
  ALSdkSettings *settings = [[ALSdkSettings alloc] init];
215
- settings.consentFlowSettings.enabled = self.consentFlowEnabledToSet.boolValue;
216
- settings.consentFlowSettings.privacyPolicyURL = self.privacyPolicyURLToSet;
217
- settings.consentFlowSettings.termsOfServiceURL = self.termsOfServiceURLToSet;
218
-
219
- self.consentFlowEnabledToSet = nil;
220
- self.privacyPolicyURLToSet = nil;
221
- self.termsOfServiceURLToSet = nil;
222
-
223
- // Initialize SDK
224
- self.sdk = [ALSdk sharedWithKey: sdkKey settings: settings];
225
- [self.sdk setPluginVersion: [@"React-Native-" stringByAppendingString: pluginVersion]];
226
- [self.sdk setMediationProvider: ALMediationProviderMAX];
227
-
228
- // Set user id if needed
229
- if ( [self.userIdentifierToSet al_isValidString] )
229
+
230
+ // Selective init
231
+ if ( self.initializationAdUnitIdentifiersToSet )
230
232
  {
231
- self.sdk.userIdentifier = self.userIdentifierToSet;
232
- self.userIdentifierToSet = nil;
233
+ settings.initializationAdUnitIdentifiers = self.initializationAdUnitIdentifiersToSet;
234
+ self.initializationAdUnitIdentifiersToSet = nil;
233
235
  }
234
-
236
+
237
+ // Deprecated consent flow which automatically moves to the new flow
238
+ if ( self.consentFlowEnabledToSet )
239
+ {
240
+ settings.consentFlowSettings.enabled = self.consentFlowEnabledToSet.boolValue;
241
+ self.consentFlowEnabledToSet = nil;
242
+
243
+ if ( self.privacyPolicyURLToSet )
244
+ {
245
+ settings.consentFlowSettings.privacyPolicyURL = self.privacyPolicyURLToSet;
246
+ self.privacyPolicyURLToSet = nil;
247
+ }
248
+
249
+ if (self.termsOfServiceURLToSet )
250
+ {
251
+ settings.consentFlowSettings.termsOfServiceURL = self.termsOfServiceURLToSet;
252
+ self.termsOfServiceURLToSet = nil;
253
+ }
254
+ }
255
+
256
+ // New terms and privacy policy flow
257
+ if ( self.termsAndPrivacyPolicyFlowEnabledToSet )
258
+ {
259
+ settings.termsAndPrivacyPolicyFlowSettings.enabled = self.termsAndPrivacyPolicyFlowEnabledToSet.boolValue;
260
+ self.termsAndPrivacyPolicyFlowEnabledToSet = nil;
261
+
262
+ if ( self.privacyPolicyURLToSet )
263
+ {
264
+ settings.termsAndPrivacyPolicyFlowSettings.privacyPolicyURL = self.privacyPolicyURLToSet;
265
+ self.privacyPolicyURLToSet = nil;
266
+ }
267
+
268
+ if ( self.termsOfServiceURLToSet )
269
+ {
270
+ settings.termsAndPrivacyPolicyFlowSettings.termsOfServiceURL = self.termsOfServiceURLToSet;
271
+ self.termsOfServiceURLToSet = nil;
272
+ }
273
+
274
+ if ( self.debugUserGeographyToSet )
275
+ {
276
+ settings.termsAndPrivacyPolicyFlowSettings.debugUserGeography = [self toAppLovinConsentFlowUserGeography: self.debugUserGeographyToSet];
277
+ self.debugUserGeographyToSet = nil;
278
+ }
279
+ }
280
+
281
+ // Set muted if needed
282
+ if ( self.mutedToSet )
283
+ {
284
+ settings.muted = self.mutedToSet;
285
+ self.mutedToSet = nil;
286
+ }
287
+
235
288
  // Set test device ids if needed
236
289
  if ( self.testDeviceIdentifiersToSet )
237
290
  {
238
- self.sdk.settings.testDeviceAdvertisingIdentifiers = self.testDeviceIdentifiersToSet;
291
+ settings.testDeviceAdvertisingIdentifiers = self.testDeviceIdentifiersToSet;
239
292
  self.testDeviceIdentifiersToSet = nil;
240
293
  }
241
294
 
242
295
  // Set verbose logging state if needed
243
296
  if ( self.verboseLoggingToSet )
244
297
  {
245
- self.sdk.settings.verboseLoggingEnabled = self.verboseLoggingToSet.boolValue;
298
+ settings.verboseLoggingEnabled = self.verboseLoggingToSet.boolValue;
246
299
  self.verboseLoggingToSet = nil;
247
300
  }
248
301
 
249
302
  // Set creative debugger enabled if needed.
250
303
  if ( self.creativeDebuggerEnabledToSet )
251
304
  {
252
- self.sdk.settings.creativeDebuggerEnabled = self.creativeDebuggerEnabledToSet.boolValue;
305
+ settings.creativeDebuggerEnabled = self.creativeDebuggerEnabledToSet.boolValue;
253
306
  self.creativeDebuggerEnabledToSet = nil;
254
307
  }
255
308
 
256
309
  // Set location collection enabled if needed
257
310
  if ( self.locationCollectionEnabledToSet )
258
311
  {
259
- self.sdk.settings.locationCollectionEnabled = self.locationCollectionEnabledToSet.boolValue;
312
+ settings.locationCollectionEnabled = self.locationCollectionEnabledToSet.boolValue;
260
313
  self.locationCollectionEnabledToSet = nil;
261
314
  }
262
315
 
316
+ [self setPendingExtraParametersIfNeeded: settings];
317
+
318
+ // Initialize SDK
319
+ self.sdk = [ALSdk sharedWithKey: sdkKey settings: settings];
320
+ [self.sdk setPluginVersion: [@"React-Native-" stringByAppendingString: pluginVersion]];
321
+ [self.sdk setMediationProvider: ALMediationProviderMAX];
322
+
323
+ // Set user id if needed
324
+ if ( [self.userIdentifierToSet al_isValidString] )
325
+ {
326
+ self.sdk.userIdentifier = self.userIdentifierToSet;
327
+ self.userIdentifierToSet = nil;
328
+ }
329
+
263
330
  if ( self.targetingYearOfBirthToSet )
264
331
  {
265
332
  self.sdk.targetingData.yearOfBirth = self.targetingYearOfBirthToSet.intValue <= 0 ? nil : self.targetingYearOfBirthToSet;
@@ -302,8 +369,6 @@ RCT_EXPORT_METHOD(initialize:(NSString *)pluginVersion :(NSString *)sdkKey :(RCT
302
369
  self.targetingInterestsToSet = nil;
303
370
  }
304
371
 
305
- [self setPendingExtraParametersIfNeeded: self.sdk.settings];
306
-
307
372
  [self.sdk initializeSdkWithCompletionHandler:^(ALSdkConfiguration *configuration) {
308
373
 
309
374
  [self log: @"SDK initialized"];
@@ -311,7 +376,10 @@ RCT_EXPORT_METHOD(initialize:(NSString *)pluginVersion :(NSString *)sdkKey :(RCT
311
376
  self.sdkConfiguration = configuration;
312
377
  self.sdkInitialized = YES;
313
378
 
314
- resolve(@{@"countryCode" : self.sdk.configuration.countryCode});
379
+ resolve(@{@"countryCode" : self.sdk.configuration.countryCode,
380
+ @"appTrackingStatus" : [self fromAppLovinAppTrackingStatus: self.sdk.configuration.appTrackingTransparencyStatus],
381
+ @"consentFlowUserGeography" : [self fromAppLovinConsentFlowUserGeography: self.sdk.configuration.consentFlowUserGeography],
382
+ @"isTestModeEnabled" : @(self.sdk.configuration.isTestModeEnabled)});
315
383
  }];
316
384
  }
317
385
 
@@ -378,9 +446,15 @@ RCT_EXPORT_METHOD(setUserId:(NSString *)userId)
378
446
 
379
447
  RCT_EXPORT_METHOD(setMuted:(BOOL)muted)
380
448
  {
381
- if ( ![self isPluginInitialized] ) return;
382
-
383
- self.sdk.settings.muted = muted;
449
+ if ( [self isPluginInitialized] )
450
+ {
451
+ self.sdk.settings.muted = muted;
452
+ self.mutedToSet = nil;
453
+ }
454
+ else
455
+ {
456
+ self.mutedToSet = @(muted);
457
+ }
384
458
  }
385
459
 
386
460
  RCT_EXPORT_METHOD(isMuted:(RCTPromiseResolveBlock)resolve :(RCTPromiseRejectBlock)reject)
@@ -447,19 +521,38 @@ RCT_EXPORT_METHOD(setExtraParameter:(NSString *)key :(nullable NSString *)value)
447
521
  }
448
522
  }
449
523
 
524
+ RCT_EXPORT_METHOD(setInitializationAdUnitIds:(NSArray<NSString *> *)adUnitIds)
525
+ {
526
+ self.initializationAdUnitIdentifiersToSet = adUnitIds;
527
+ }
528
+
529
+ #pragma mark - MAX Terms and Privacy Policy Flow
530
+
450
531
  RCT_EXPORT_METHOD(setConsentFlowEnabled:(BOOL)enabled)
451
532
  {
452
533
  self.consentFlowEnabledToSet = @(enabled);
453
534
  }
535
+
536
+ RCT_EXPORT_METHOD(setTermsAndPrivacyPolicyFlowEnabled:(BOOL)enabled)
537
+ {
538
+ self.termsAndPrivacyPolicyFlowEnabledToSet = @(enabled);
539
+ }
540
+
454
541
  RCT_EXPORT_METHOD(setPrivacyPolicyUrl:(NSString *)urlString)
455
542
  {
456
543
  self.privacyPolicyURLToSet = [NSURL URLWithString: urlString];
457
544
  }
545
+
458
546
  RCT_EXPORT_METHOD(setTermsOfServiceUrl:(NSString *)urlString)
459
547
  {
460
548
  self.termsOfServiceURLToSet = [NSURL URLWithString: urlString];
461
549
  }
462
550
 
551
+ RCT_EXPORT_METHOD(setConsentFlowDebugUserGeography:(NSString *)userGeography)
552
+ {
553
+ self.debugUserGeographyToSet = userGeography;
554
+ }
555
+
463
556
  #pragma mark - Data Passing
464
557
 
465
558
  RCT_EXPORT_METHOD(setTargetingDataYearOfBirth:(nonnull NSNumber *)yearOfBirth)
@@ -1971,6 +2064,56 @@ RCT_EXPORT_METHOD(setAppOpenAdLocalExtraParameter:(NSString *)adUnitIdentifier :
1971
2064
  return ALAdContentRatingNone;
1972
2065
  }
1973
2066
 
2067
+ - (ALConsentFlowUserGeography)toAppLovinConsentFlowUserGeography:(NSString *)userGeography
2068
+ {
2069
+ if ( [USER_GEOGRAPHY_GDPR al_isEqualToStringIgnoringCase: userGeography] )
2070
+ {
2071
+ return ALConsentFlowUserGeographyGDPR;
2072
+ }
2073
+ else if ( [USER_GEOGRAPHY_OTHER al_isEqualToStringIgnoringCase: userGeography] )
2074
+ {
2075
+ return ALConsentFlowUserGeographyOther;
2076
+ }
2077
+
2078
+ return ALConsentFlowUserGeographyUnknown;
2079
+ }
2080
+
2081
+ - (NSString *)fromAppLovinConsentFlowUserGeography:(ALConsentFlowUserGeography)userGeography
2082
+ {
2083
+ if ( ALConsentFlowUserGeographyGDPR == userGeography )
2084
+ {
2085
+ return USER_GEOGRAPHY_GDPR;
2086
+ }
2087
+ else if ( ALConsentFlowUserGeographyOther == userGeography )
2088
+ {
2089
+ return USER_GEOGRAPHY_OTHER;
2090
+ }
2091
+
2092
+ return USER_GEOGRAPHY_UNKNOWN;
2093
+ }
2094
+
2095
+ - (NSString *)fromAppLovinAppTrackingStatus:(ALAppTrackingTransparencyStatus)status
2096
+ {
2097
+ if ( ALAppTrackingTransparencyStatusNotDetermined == status )
2098
+ {
2099
+ return APP_TRACKING_STATUS_NOTDETERMINED;
2100
+ }
2101
+ else if ( ALAppTrackingTransparencyStatusRestricted == status )
2102
+ {
2103
+ return APP_TRACKING_STATUS_RESTRICTED;
2104
+ }
2105
+ else if ( ALAppTrackingTransparencyStatusDenied == status )
2106
+ {
2107
+ return APP_TRACKING_STATUS_DENIED;
2108
+ }
2109
+ else if ( ALAppTrackingTransparencyStatusAuthorized == status )
2110
+ {
2111
+ return APP_TRACKING_STATUS_AUTHORIZED;
2112
+ }
2113
+
2114
+ return APP_TRACKING_STATUS_UNAVAILABLE;
2115
+ }
2116
+
1974
2117
  #pragma mark - Ad Info
1975
2118
 
1976
2119
  - (NSDictionary<NSString *, id> *)adInfoForAd:(MAAd *)ad
@@ -31,6 +31,7 @@
31
31
  @property (nonatomic, strong, nullable) MANativeAdLoader *adLoader;
32
32
  @property (nonatomic, strong, nullable) MAAd *nativeAd;
33
33
  @property (nonatomic, strong) ALAtomicBoolean *isLoading; // Guard against repeated ad loads
34
+ @property (nonatomic, strong) ALAtomicBoolean *isAdUnitIdSet;
34
35
 
35
36
  // JavaScript properties
36
37
  @property (nonatomic, copy) NSString *adUnitId;
@@ -59,6 +60,7 @@
59
60
  {
60
61
  self.bridge = bridge;
61
62
  self.isLoading = [[ALAtomicBoolean alloc] init];
63
+ self.isAdUnitIdSet = [[ALAtomicBoolean alloc] init];
62
64
  self.clickableViews = [NSMutableArray array];
63
65
  }
64
66
  return self;
@@ -95,10 +97,7 @@
95
97
 
96
98
  _adUnitId = adUnitId;
97
99
 
98
- // Explicitly invoke ad load now that Ad Unit ID is set, but do so after 0.25s to allow other props to set
99
- dispatchOnMainQueueAfter(0.25, ^{
100
- [self loadAd];
101
- });
100
+ [self.isAdUnitIdSet set: YES];
102
101
  }
103
102
 
104
103
  // Called when Ad Unit ID is set, and via RN layer
@@ -267,6 +266,26 @@
267
266
  [self.nativeAd.nativeAd.mediaView al_pinToSuperview];
268
267
  }
269
268
 
269
+ /**
270
+ * Invoked:
271
+ * 1. after all the JavaScript properties are set when mounting NativeAdView
272
+ * 2. after all the user's asset views are mounted, following the 1st event
273
+ */
274
+ - (void)didSetProps:(NSArray<NSString *> *)changedProps
275
+ {
276
+ if ( [self.isAdUnitIdSet compareAndSet:YES update: NO] )
277
+ {
278
+ [self loadAd];
279
+ }
280
+ else
281
+ {
282
+ if ( !self.adLoader ) return;
283
+
284
+ [self.adLoader registerClickableViews: self.clickableViews withContainer: self forAd: self.nativeAd];
285
+ [self.adLoader handleNativeAdViewRenderedForAd: self.nativeAd];
286
+ }
287
+ }
288
+
270
289
  #pragma mark - Ad Loader Delegate
271
290
 
272
291
  - (void)didLoadNativeAd:(nullable MANativeAdView *)nativeAdView forAd:(MAAd *)ad
@@ -291,14 +310,7 @@
291
310
  // Notify `AppLovinNativeAdView.js`
292
311
  [self sendAdLoadedReactNativeEventForAd: ad.nativeAd];
293
312
 
294
- // After notifying the RN layer - have slight delay to let views bind to this layer in `clickableViews` before registering
295
- dispatchOnMainQueueAfter(0.5, ^{
296
-
297
- [self.adLoader registerClickableViews: self.clickableViews withContainer: self forAd: ad];
298
- [self.adLoader handleNativeAdViewRenderedForAd: ad];
299
-
300
- [self.isLoading set: NO];
301
- });
313
+ [self.isLoading set: NO];
302
314
  }
303
315
 
304
316
  - (void)sendAdLoadedReactNativeEventForAd:(MANativeAd *)ad
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', '12.0.0'
38
+ pod 'AppLovinSDK', '12.1.0'
39
39
 
40
40
  end
package/ios/Podfile.lock CHANGED
@@ -1,5 +1,5 @@
1
1
  PODS:
2
- - AppLovinSDK (12.0.0)
2
+ - AppLovinSDK (12.1.0)
3
3
  - boost-for-react-native (1.63.0)
4
4
  - DoubleConversion (1.1.6)
5
5
  - FBLazyVector (0.63.5)
@@ -249,7 +249,7 @@ PODS:
249
249
  - Yoga (1.14.0)
250
250
 
251
251
  DEPENDENCIES:
252
- - AppLovinSDK (= 12.0.0)
252
+ - AppLovinSDK (= 12.1.0)
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: 15679e9f576a4d8662e1dc537c9a4ed47d3292a5
342
+ AppLovinSDK: 179d509c258e01a3a77eb8416f0ba843a12ed322
343
343
  boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
344
344
  DoubleConversion: cde416483dac037923206447da6e1454df403714
345
345
  FBLazyVector: 352a8ca9bbc8e2f097d680747a8c97ecef12d469
@@ -368,6 +368,6 @@ SPEC CHECKSUMS:
368
368
  ReactCommon: b9ff54b6dd22ba4a776eda22d7f83ec27544ca35
369
369
  Yoga: 0276e9f20976c8568e107cfc1163a8629051adc0
370
370
 
371
- PODFILE CHECKSUM: dc95f857ab3004d6fc04e845d974091e28859c7b
371
+ PODFILE CHECKSUM: d7248805481768209533def6ca165110984d9914
372
372
 
373
373
  COCOAPODS: 1.11.3
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-native-applovin-max",
3
3
  "author": "AppLovin Corporation",
4
- "version": "6.0.2",
4
+ "version": "6.1.1",
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_6_0_2" }
14
+ s.source = { :git => "https://github.com/AppLovin/AppLovin-MAX-React-Native.git", :tag => "release_6_1_1" }
15
15
 
16
16
  s.source_files = "ios/AppLovinMAX*.{h,m}"
17
17
 
18
18
  s.dependency "React"
19
- s.dependency "AppLovinSDK", "12.0.0"
19
+ s.dependency "AppLovinSDK", "12.1.0"
20
20
  end
package/src/AdView.tsx CHANGED
@@ -1,4 +1,5 @@
1
- import React, { useEffect, useState } from 'react';
1
+ import * as React from 'react';
2
+ import { useEffect, useState } from 'react';
2
3
  import { NativeModules, requireNativeComponent, StyleSheet } from 'react-native';
3
4
  import type { ViewProps, ViewStyle, StyleProp } from 'react-native';
4
5
  import type { AdDisplayFailedInfo, AdInfo, AdLoadFailedInfo, AdRevenueInfo } from './types/AdInfo';
@@ -78,8 +79,8 @@ const getOutlineViewSize = (style: StyleProp<ViewStyle>) => {
78
79
  const sizeAdViewDimensions = (
79
80
  adFormat: AdFormat,
80
81
  adaptiveBannerEnabled?: boolean,
81
- width?: number | string,
82
- height?: number | string
82
+ width?: number | string | null,
83
+ height?: number | string | null
83
84
  ): Promise<Record<string, number>> => {
84
85
  const sizeForBannerFormat = async () => {
85
86
  const isTablet = await AppLovinMAX.isTablet();
@@ -194,6 +195,8 @@ export const AdView = ({
194
195
  useEffect(() => {
195
196
  if (!isInitialized) return;
196
197
  const [width, height] = getOutlineViewSize(style);
198
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
199
+ // @ts-ignore: width and height should be of type DimensionValue in react-native 0.72.0 and above
197
200
  sizeAdViewDimensions(adFormat, adaptiveBannerEnabled, width, height).then((value: Record<string, number>) => {
198
201
  setDimensions(value);
199
202
  });
@@ -4,7 +4,7 @@ import type { Configuration } from './types/Configuration';
4
4
 
5
5
  const NativeAppLovinMAX = NativeModules.AppLovinMAX;
6
6
 
7
- const VERSION = '6.0.2';
7
+ const VERSION = '6.1.1';
8
8
 
9
9
  const initialize = async (sdkKey: string): Promise<Configuration> => {
10
10
  return NativeAppLovinMAX.initialize(VERSION, sdkKey);
package/src/Privacy.ts CHANGED
@@ -3,4 +3,60 @@ import type { PrivacyType } from './types/Privacy';
3
3
 
4
4
  const { AppLovinMAX } = NativeModules;
5
5
 
6
+ /**
7
+ * This enum represents the user's geography used to determine the type of consent flow shown to the
8
+ * user.
9
+ */
10
+ export enum ConsentFlowUserGeography {
11
+ /**
12
+ * User's geography is unknown.
13
+ */
14
+ UNKNOWN = 'U',
15
+
16
+ /**
17
+ * The user is in GDPR region.
18
+ */
19
+ GDPR = 'G',
20
+
21
+ /**
22
+ * The user is in a non-GDPR region.
23
+ */
24
+ OTHER = 'O',
25
+ }
26
+
27
+ /**
28
+ * AppLovin SDK-defined app tracking transparency status values (extended to include "unavailable"
29
+ * state on iOS before iOS14).
30
+ */
31
+ export enum AppTrackingStatus {
32
+ /**
33
+ * Device is on iOS before iOS14, AppTrackingTransparency.framework is not available.
34
+ */
35
+ UNAVAILABLE = 'U',
36
+
37
+ /**
38
+ * The user has not yet received an authorization request to authorize access to app-related
39
+ * data that can be used for tracking the user or the device.
40
+ */
41
+ NOT_DETERMINED = 'N',
42
+
43
+ /**
44
+ * Authorization to access app-related data that can be used for tracking the user or the device
45
+ * is restricted.
46
+ */
47
+ RESTRICTED = 'R',
48
+
49
+ /**
50
+ * The user denies authorization to access app-related data that can be used for tracking the
51
+ * user or the device.
52
+ */
53
+ DENIED = 'D',
54
+
55
+ /**
56
+ * The user authorizes access to app-related data that can be used for tracking the user or the
57
+ * device.
58
+ */
59
+ AUTHORIZED = 'A',
60
+ }
61
+
6
62
  export const Privacy: PrivacyType = AppLovinMAX;
@@ -27,20 +27,20 @@ const nativeMethods: NativeTargetingDataType = AppLovinMAX;
27
27
  * This enumeration represents content ratings for the ads shown to users.
28
28
  */
29
29
  export enum AdContentRating {
30
- None = 0,
31
- AllAudiences = 1,
32
- EveryoneOverTwelve = 2,
33
- MatureAudiences = 3,
30
+ NONE = 0,
31
+ ALL_AUDIENCES = 1,
32
+ EVERYONE_OVER_TWELVE = 2,
33
+ MATURE_AUDIENCES = 3,
34
34
  }
35
35
 
36
36
  /**
37
37
  * This enumeration represents gender.
38
38
  */
39
39
  export enum UserGender {
40
- Unknown = 'U',
41
- Female = 'F',
42
- Male = 'M',
43
- Other = 'O',
40
+ UNKNOWN = 'U',
41
+ FEMALE = 'F',
42
+ MALE = 'M',
43
+ OTHER = 'O',
44
44
  }
45
45
 
46
46
  /**
@@ -72,10 +72,10 @@ export const TargetingData: TargetingDataType = {
72
72
  */
73
73
  set gender(value: UserGender | Promise<UserGender>) {
74
74
  if (
75
- value === UserGender.Unknown ||
76
- value === UserGender.Female ||
77
- value === UserGender.Male ||
78
- value === UserGender.Other
75
+ value === UserGender.UNKNOWN ||
76
+ value === UserGender.FEMALE ||
77
+ value === UserGender.MALE ||
78
+ value === UserGender.OTHER
79
79
  ) {
80
80
  nativeMethods.setTargetingDataGender(value);
81
81
  } else {
@@ -99,10 +99,10 @@ export const TargetingData: TargetingDataType = {
99
99
  */
100
100
  set maximumAdContentRating(value: AdContentRating | Promise<AdContentRating>) {
101
101
  if (
102
- value === AdContentRating.None ||
103
- value === AdContentRating.AllAudiences ||
104
- value === AdContentRating.EveryoneOverTwelve ||
105
- value === AdContentRating.MatureAudiences
102
+ value === AdContentRating.NONE ||
103
+ value === AdContentRating.ALL_AUDIENCES ||
104
+ value === AdContentRating.EVERYONE_OVER_TWELVE ||
105
+ value === AdContentRating.MATURE_AUDIENCES
106
106
  ) {
107
107
  nativeMethods.setTargetingDataMaximumAdContentRating(value);
108
108
  } else {
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { default, AppLovinMAX } from './AppLovinMAX';
2
- export { Privacy } from './Privacy';
2
+ export { Privacy, ConsentFlowUserGeography, AppTrackingStatus } from './Privacy';
3
3
  export { TargetingData, AdContentRating, UserGender } from './TargetingData';
4
4
  export { InterstitialAd } from './InterstitialAd';
5
5
  export { RewardedAd } from './RewardedAd';
@@ -1,4 +1,5 @@
1
- import React, { forwardRef, useContext, useImperativeHandle, useRef, useState, useEffect, useCallback } from 'react';
1
+ import * as React from 'react';
2
+ import { forwardRef, useContext, useImperativeHandle, useRef, useState, useEffect, useCallback } from 'react';
2
3
  import { NativeModules, requireNativeComponent, UIManager, findNodeHandle } from 'react-native';
3
4
  import type { ViewProps } from 'react-native';
4
5
  import { NativeAdViewContext, NativeAdViewProvider } from './NativeAdViewProvider';
@@ -1,4 +1,5 @@
1
- import React, { useContext, useRef, useEffect } from 'react';
1
+ import * as React from 'react';
2
+ import { useContext, useRef, useEffect } from 'react';
2
3
  import type { ReactNode } from 'react';
3
4
  import { findNodeHandle, Text, Image, View, TouchableOpacity, StyleSheet } from 'react-native';
4
5
  import type { ViewProps, ImageProps, TextStyle, StyleProp, TextProps } from 'react-native';
@@ -1,4 +1,5 @@
1
- import React, { useState, createContext } from 'react';
1
+ import * as React from 'react';
2
+ import { useState, createContext } from 'react';
2
3
  import type { NativeMethods } from 'react-native';
3
4
  import type { NativeAd } from '../types/NativeAd';
4
5
  import type { NativeAdViewProps } from '../types/NativeAdViewProps';
@@ -17,6 +17,13 @@ export type AppLovinMAXType = {
17
17
  */
18
18
  initialize(sdkKey: string): Promise<Configuration>;
19
19
 
20
+ /**
21
+ * Sets a list of the ad units for the SDK to initialize only those networks.
22
+ *
23
+ * @param adUnitIds Ad units to be initialized with the SDK.
24
+ */
25
+ setInitializationAdUnitIds(adUnitIds: string[]): void;
26
+
20
27
  /**
21
28
  * Presents the mediation debugger UI.
22
29
  */
@@ -1,3 +1,5 @@
1
+ import type { ConsentFlowUserGeography, AppTrackingStatus } from '../Privacy';
2
+
1
3
  /**
2
4
  * Encapsulates data for the AppLovinMAX SDK configuration.
3
5
  */
@@ -6,4 +8,29 @@ export type Configuration = {
6
8
  * The country code of this user.
7
9
  */
8
10
  countryCode: string;
11
+
12
+ /**
13
+ * The user's geography used to determine the type of consent flow shown to the user. If no
14
+ * such determination could be made, {@link ConsentFlowUserGeography.UNKNOWN} will be returned.
15
+ */
16
+ consentFlowUserGeography: ConsentFlowUserGeography;
17
+
18
+ /**
19
+ * Indicates whether or not the user authorizes access to app-related data that can be used for
20
+ * tracking the user or the device.
21
+ *
22
+ * Note: available only on iOS
23
+ */
24
+ appTrackingStatus?: AppTrackingStatus;
25
+
26
+ /**
27
+ * Whether or not test mode is enabled for this session.
28
+ *
29
+ * @return {boolean} true in one of the following cases:
30
+ * 1. {@link AppLovinMAX.setTestDeviceAdvertisingIds()} was called with current device's GAID prior to SDK initialization.
31
+ * 2. Current device was registered as a test device through MAX dashboard -> MAX Test Devices prior to SDK initialization.
32
+ * 3. Test mode was manually enabled for this session through the Mediation Debugger during the last session.
33
+ * 4. Current device is an emulator.
34
+ */
35
+ isTestModeEnabled: boolean;
9
36
  };
@@ -1,3 +1,5 @@
1
+ import type { ConsentFlowUserGeography } from '../Privacy';
2
+
1
3
  export type PrivacyType = {
2
4
  /**********************************************************************************/
3
5
  /* Privacy */
@@ -44,11 +46,20 @@ export type PrivacyType = {
44
46
  /**********************************************************************************/
45
47
 
46
48
  /**
49
+ * @deprecated Use {@link setTermsAndPrivacyPolicyFlowEnabled()} instead.
50
+ *
47
51
  * Enables the MAX Terms Flow.
48
52
  *
49
53
  * @param enabled true to enable the MAX Terms Flow.
50
54
  */
51
- setConsentFlowEnabled(enabled: boolean): Promise<void>;
55
+ setConsentFlowEnabled(enabled: boolean): void;
56
+
57
+ /**
58
+ * Enables the MAX Terms and Privacy Policy Flow.
59
+ *
60
+ * @param enabled true to enable the MAX Terms and Privacy Policy Flow.
61
+ */
62
+ setTermsAndPrivacyPolicyFlowEnabled(enabled: boolean): void;
52
63
 
53
64
  /**
54
65
  * The URL of your company’s privacy policy, as a string. This is required in order to enable
@@ -56,7 +67,7 @@ export type PrivacyType = {
56
67
  *
57
68
  * @param urlString The URL string to point your company’s privacy policy.
58
69
  */
59
- setPrivacyPolicyUrl(urlString: string): Promise<void>;
70
+ setPrivacyPolicyUrl(urlString: string): void;
60
71
 
61
72
  /**
62
73
  * The URL of your company’s terms of service, as a string. This is optional; you can enable
@@ -64,5 +75,12 @@ export type PrivacyType = {
64
75
  *
65
76
  * @param urlString The URL string to point your company’s terms of service.
66
77
  */
67
- setTermsOfServiceUrl(urlString: string): Promise<void>;
78
+ setTermsOfServiceUrl(urlString: string): void;
79
+
80
+ /**
81
+ * Set debug user geography. You may use this to test CMP flow by setting this to {@link ConsentFlowUserGeography.GDPR}.
82
+ *
83
+ * @note The debug geography is used only when the app is in debug mode.
84
+ */
85
+ setConsentFlowDebugUserGeography(userGeography: ConsentFlowUserGeography): void;
68
86
  };