react-native-applovin-max 2.2.0 → 2.4.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.
@@ -41,8 +41,8 @@ android {
41
41
  defaultConfig {
42
42
  minSdkVersion 16
43
43
  targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
44
- versionCode 2020000
45
- versionName "2.2.0"
44
+ versionCode 2040000
45
+ versionName "2.4.0"
46
46
  }
47
47
 
48
48
  flavorDimensions("default")
@@ -151,10 +151,5 @@ dependencies {
151
151
 
152
152
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
153
153
 
154
- if (findProject(':Android-SDK') != null) {
155
- implementation "com.google.android.gms:play-services-ads-identifier:${versions.playServicesIdentifier}"
156
- implementation project(':Android-SDK')
157
- } else {
158
- implementation 'com.applovin:applovin-sdk:+'
159
- }
154
+ implementation 'com.applovin:applovin-sdk:+'
160
155
  }
@@ -1,84 +1,84 @@
1
- @if "%DEBUG%" == "" @echo off
2
- @rem ##########################################################################
3
- @rem
4
- @rem Gradle startup script for Windows
5
- @rem
6
- @rem ##########################################################################
7
-
8
- @rem Set local scope for the variables with windows NT shell
9
- if "%OS%"=="Windows_NT" setlocal
10
-
11
- set DIRNAME=%~dp0
12
- if "%DIRNAME%" == "" set DIRNAME=.
13
- set APP_BASE_NAME=%~n0
14
- set APP_HOME=%DIRNAME%
15
-
16
- @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17
- set DEFAULT_JVM_OPTS=
18
-
19
- @rem Find java.exe
20
- if defined JAVA_HOME goto findJavaFromJavaHome
21
-
22
- set JAVA_EXE=java.exe
23
- %JAVA_EXE% -version >NUL 2>&1
24
- if "%ERRORLEVEL%" == "0" goto init
25
-
26
- echo.
27
- echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28
- echo.
29
- echo Please set the JAVA_HOME variable in your environment to match the
30
- echo location of your Java installation.
31
-
32
- goto fail
33
-
34
- :findJavaFromJavaHome
35
- set JAVA_HOME=%JAVA_HOME:"=%
36
- set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37
-
38
- if exist "%JAVA_EXE%" goto init
39
-
40
- echo.
41
- echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42
- echo.
43
- echo Please set the JAVA_HOME variable in your environment to match the
44
- echo location of your Java installation.
45
-
46
- goto fail
47
-
48
- :init
49
- @rem Get command-line arguments, handling Windows variants
50
-
51
- if not "%OS%" == "Windows_NT" goto win9xME_args
52
-
53
- :win9xME_args
54
- @rem Slurp the command line arguments.
55
- set CMD_LINE_ARGS=
56
- set _SKIP=2
57
-
58
- :win9xME_args_slurp
59
- if "x%~1" == "x" goto execute
60
-
61
- set CMD_LINE_ARGS=%*
62
-
63
- :execute
64
- @rem Setup the command line
65
-
66
- set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67
-
68
- @rem Execute Gradle
69
- "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70
-
71
- :end
72
- @rem End local scope for the variables with windows NT shell
73
- if "%ERRORLEVEL%"=="0" goto mainEnd
74
-
75
- :fail
76
- rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77
- rem the _cmd.exe /c_ return code!
78
- if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79
- exit /b 1
80
-
81
- :mainEnd
82
- if "%OS%"=="Windows_NT" endlocal
83
-
84
- :omega
1
+ @if "%DEBUG%" == "" @echo off
2
+ @rem ##########################################################################
3
+ @rem
4
+ @rem Gradle startup script for Windows
5
+ @rem
6
+ @rem ##########################################################################
7
+
8
+ @rem Set local scope for the variables with windows NT shell
9
+ if "%OS%"=="Windows_NT" setlocal
10
+
11
+ set DIRNAME=%~dp0
12
+ if "%DIRNAME%" == "" set DIRNAME=.
13
+ set APP_BASE_NAME=%~n0
14
+ set APP_HOME=%DIRNAME%
15
+
16
+ @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17
+ set DEFAULT_JVM_OPTS=
18
+
19
+ @rem Find java.exe
20
+ if defined JAVA_HOME goto findJavaFromJavaHome
21
+
22
+ set JAVA_EXE=java.exe
23
+ %JAVA_EXE% -version >NUL 2>&1
24
+ if "%ERRORLEVEL%" == "0" goto init
25
+
26
+ echo.
27
+ echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28
+ echo.
29
+ echo Please set the JAVA_HOME variable in your environment to match the
30
+ echo location of your Java installation.
31
+
32
+ goto fail
33
+
34
+ :findJavaFromJavaHome
35
+ set JAVA_HOME=%JAVA_HOME:"=%
36
+ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37
+
38
+ if exist "%JAVA_EXE%" goto init
39
+
40
+ echo.
41
+ echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42
+ echo.
43
+ echo Please set the JAVA_HOME variable in your environment to match the
44
+ echo location of your Java installation.
45
+
46
+ goto fail
47
+
48
+ :init
49
+ @rem Get command-line arguments, handling Windows variants
50
+
51
+ if not "%OS%" == "Windows_NT" goto win9xME_args
52
+
53
+ :win9xME_args
54
+ @rem Slurp the command line arguments.
55
+ set CMD_LINE_ARGS=
56
+ set _SKIP=2
57
+
58
+ :win9xME_args_slurp
59
+ if "x%~1" == "x" goto execute
60
+
61
+ set CMD_LINE_ARGS=%*
62
+
63
+ :execute
64
+ @rem Setup the command line
65
+
66
+ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67
+
68
+ @rem Execute Gradle
69
+ "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70
+
71
+ :end
72
+ @rem End local scope for the variables with windows NT shell
73
+ if "%ERRORLEVEL%"=="0" goto mainEnd
74
+
75
+ :fail
76
+ rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77
+ rem the _cmd.exe /c_ return code!
78
+ if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79
+ exit /b 1
80
+
81
+ :mainEnd
82
+ if "%OS%"=="Windows_NT" endlocal
83
+
84
+ :omega
@@ -2,16 +2,15 @@ package com.applovin.reactnative;
2
2
 
3
3
  import android.app.Activity;
4
4
  import android.content.Context;
5
- import android.graphics.Point;
6
5
  import android.text.TextUtils;
7
- import android.view.ViewGroup;
8
- import android.view.ViewParent;
9
6
 
10
7
  import com.applovin.mediation.MaxAdFormat;
11
8
  import com.applovin.mediation.ads.MaxAdView;
12
9
  import com.facebook.react.uimanager.ThemedReactContext;
13
10
  import com.facebook.react.views.view.ReactViewGroup;
14
11
 
12
+ import androidx.annotation.Nullable;
13
+
15
14
  /**
16
15
  * Created by Thomas So on September 27 2020
17
16
  */
@@ -69,9 +68,15 @@ class AppLovinMAXAdView
69
68
  }
70
69
  }
71
70
 
72
- public void maybeAttachAdView(final String adUnitId, final MaxAdFormat adFormat)
71
+ @Nullable
72
+ protected MaxAdView getAdView()
73
+ {
74
+ return adView;
75
+ }
76
+
77
+ public void maybeAttachAdView(final String placement, final String adaptiveBannerEnabledStr, final String adUnitId, final MaxAdFormat adFormat)
73
78
  {
74
- Activity currentActivity = reactContext.getCurrentActivity();
79
+ final Activity currentActivity = reactContext.getCurrentActivity();
75
80
  if ( currentActivity == null )
76
81
  {
77
82
  AppLovinMAXModule.e( "Unable to attach AdView - no current Activity found" );
@@ -87,19 +92,24 @@ class AppLovinMAXAdView
87
92
  // If ad unit id and format has been set - create and attach AdView
88
93
  if ( !TextUtils.isEmpty( adUnitId ) && adFormat != null )
89
94
  {
90
- adView = AppLovinMAXModule.getInstance().retrieveAdView( adUnitId, adFormat, "", new Point( 0, 0 ) );
91
- adView.loadAd();
95
+ adView = new MaxAdView( adUnitId, adFormat, AppLovinMAXModule.getInstance().getSdk(), currentActivity );
96
+ adView.setListener( AppLovinMAXModule.getInstance() );
92
97
 
93
- currentWidthPx = getWidth();
94
- currentHeightPx = getHeight();
98
+ if ( placement != null )
99
+ {
100
+ adView.setPlacement( placement );
101
+ }
95
102
 
96
- // Handle fast refresh cases of re-adding adView
97
- ViewParent parent = adView.getParent();
98
- if ( parent instanceof ViewGroup )
103
+ if ( adaptiveBannerEnabledStr != null )
99
104
  {
100
- ( (ViewGroup) parent ).removeView( adView );
105
+ adView.setExtraParameter( "adaptive_banner", adaptiveBannerEnabledStr );
101
106
  }
102
107
 
108
+ adView.loadAd();
109
+
110
+ currentWidthPx = getWidth();
111
+ currentHeightPx = getHeight();
112
+
103
113
  addView( adView );
104
114
  }
105
115
  }
@@ -1,6 +1,7 @@
1
1
  package com.applovin.reactnative;
2
2
 
3
3
  import com.applovin.mediation.MaxAdFormat;
4
+ import com.applovin.mediation.ads.MaxAdView;
4
5
  import com.facebook.react.bridge.ReactApplicationContext;
5
6
  import com.facebook.react.bridge.ReadableArray;
6
7
  import com.facebook.react.uimanager.SimpleViewManager;
@@ -28,6 +29,10 @@ class AppLovinMAXAdViewManager
28
29
  private final Map<AppLovinMAXAdView, String> adUnitIdRegistry = new HashMap<>();
29
30
  private final Map<AppLovinMAXAdView, MaxAdFormat> adFormatRegistry = new HashMap<>();
30
31
 
32
+ // Storage for placement and extra parameters if set before the MAAdView is created
33
+ private final Map<AppLovinMAXAdView, String> placementRegistry = new HashMap<>();
34
+ private final Map<AppLovinMAXAdView, String> adaptiveBannerEnabledRegistry = new HashMap<>();
35
+
31
36
  public AppLovinMAXAdViewManager(final ReactApplicationContext reactApplicationContext)
32
37
  {
33
38
  this.reactApplicationContext = reactApplicationContext;
@@ -49,13 +54,26 @@ class AppLovinMAXAdViewManager
49
54
  @Override
50
55
  public void receiveCommand(@NonNull AppLovinMAXAdView view, String commandId, @Nullable ReadableArray args)
51
56
  {
52
- if ( "setAdUnitId".equals( commandId ) && args != null )
57
+ if ( args == null ) return;
58
+
59
+ String arg = args.getString( 0 );
60
+ if ( arg == null ) return;
61
+
62
+ if ( "setPlacement".equals( commandId ) )
63
+ {
64
+ setPlacement( view, arg );
65
+ }
66
+ else if ( "setAdaptiveBannerEnabled".equals( commandId ) )
53
67
  {
54
- setAdUnitId( view, args.getString( 0 ) );
68
+ setAdaptiveBannerEnabled( view, arg );
55
69
  }
56
- else if ( "setAdFormat".equals( commandId ) && args != null )
70
+ else if ( "setAdUnitId".equals( commandId ) )
57
71
  {
58
- setAdFormat( view, args.getString( 0 ) );
72
+ setAdUnitId( view, arg );
73
+ }
74
+ else if ( "setAdFormat".equals( commandId ) )
75
+ {
76
+ setAdFormat( view, arg );
59
77
  }
60
78
  else
61
79
  {
@@ -63,11 +81,44 @@ class AppLovinMAXAdViewManager
63
81
  }
64
82
  }
65
83
 
84
+ public void setPlacement(final AppLovinMAXAdView view, final String placement)
85
+ {
86
+ // Post to main thread to avoid race condition with actual creation of MaxAdView in maybeAttachAdView()
87
+ view.post( () -> {
88
+
89
+ MaxAdView adView = view.getAdView();
90
+ if ( adView != null )
91
+ {
92
+ adView.setPlacement( placement );
93
+ }
94
+ else
95
+ {
96
+ placementRegistry.put( view, placement );
97
+ }
98
+ } );
99
+ }
100
+
101
+ public void setAdaptiveBannerEnabled(final AppLovinMAXAdView view, final String enabledStr)
102
+ {
103
+ // Post to main thread to avoid race condition with actual creation of MaxAdView in maybeAttachAdView()
104
+ view.post( () -> {
105
+
106
+ MaxAdView adView = view.getAdView();
107
+ if ( adView != null )
108
+ {
109
+ adView.setExtraParameter( "adaptive_banner", enabledStr );
110
+ }
111
+ else
112
+ {
113
+ adaptiveBannerEnabledRegistry.put( view, enabledStr );
114
+ }
115
+ } );
116
+ }
117
+
66
118
  public void setAdUnitId(final AppLovinMAXAdView view, final String adUnitId)
67
119
  {
68
120
  adUnitIdRegistry.put( view, adUnitId );
69
-
70
- view.maybeAttachAdView( adUnitIdRegistry.get( view ), adFormatRegistry.get( view ) );
121
+ maybeAttachAdView( view );
71
122
  }
72
123
 
73
124
  public void setAdFormat(final AppLovinMAXAdView view, final String adFormatStr)
@@ -81,7 +132,18 @@ class AppLovinMAXAdViewManager
81
132
  adFormatRegistry.put( view, MaxAdFormat.MREC );
82
133
  }
83
134
 
84
- view.maybeAttachAdView( adUnitIdRegistry.get( view ), adFormatRegistry.get( view ) );
135
+ maybeAttachAdView( view );
136
+ }
137
+
138
+ private void maybeAttachAdView(final AppLovinMAXAdView view)
139
+ {
140
+ String placement = placementRegistry.remove( view );
141
+ String adaptiveBannerEnabledStr = adaptiveBannerEnabledRegistry.remove( view );
142
+
143
+ view.maybeAttachAdView( placement,
144
+ adaptiveBannerEnabledStr,
145
+ adUnitIdRegistry.get( view ),
146
+ adFormatRegistry.get( view ) );
85
147
  }
86
148
 
87
149
  @Override
@@ -46,8 +46,10 @@ import com.facebook.react.bridge.WritableMap;
46
46
 
47
47
  import java.util.ArrayList;
48
48
  import java.util.HashMap;
49
+ import java.util.HashSet;
49
50
  import java.util.List;
50
51
  import java.util.Map;
52
+ import java.util.Set;
51
53
  import java.util.concurrent.TimeUnit;
52
54
 
53
55
  import androidx.annotation.Nullable;
@@ -87,19 +89,25 @@ public class AppLovinMAXModule
87
89
  private final Map<String, MaxRewardedAd> mRewardedAds = new HashMap<>( 2 );
88
90
 
89
91
  // Banner Fields
90
- private final Map<String, MaxAdView> mAdViews = new HashMap<>( 2 );
91
- private final Map<String, MaxAdFormat> mAdViewAdFormats = new HashMap<>( 2 );
92
- private final Map<String, String> mAdViewPositions = new HashMap<>( 2 );
93
- private final Map<String, Point> mAdViewOffsets = new HashMap<>( 2 );
94
- private final Map<String, Integer> mAdViewWidths = new HashMap<>( 2 );
95
- private final Map<String, MaxAdFormat> mVerticalAdViewFormats = new HashMap<>( 2 );
96
- private final List<String> mAdUnitIdsToShowAfterCreate = new ArrayList<>( 2 );
92
+ private final Map<String, MaxAdView> mAdViews = new HashMap<>( 2 );
93
+ private final Map<String, MaxAdFormat> mAdViewAdFormats = new HashMap<>( 2 );
94
+ private final Map<String, String> mAdViewPositions = new HashMap<>( 2 );
95
+ private final Map<String, Point> mAdViewOffsets = new HashMap<>( 2 );
96
+ private final Map<String, Integer> mAdViewWidths = new HashMap<>( 2 );
97
+ private final Map<String, MaxAdFormat> mVerticalAdViewFormats = new HashMap<>( 2 );
98
+ private final List<String> mAdUnitIdsToShowAfterCreate = new ArrayList<>( 2 );
99
+ private final Set<String> mDisabledAdaptiveBannerAdUnitIds = new HashSet<>( 2 );
97
100
 
98
101
  public static AppLovinMAXModule getInstance()
99
102
  {
100
103
  return instance;
101
104
  }
102
105
 
106
+ public AppLovinSdk getSdk()
107
+ {
108
+ return sdk;
109
+ }
110
+
103
111
  public AppLovinMAXModule(final ReactApplicationContext reactContext)
104
112
  {
105
113
  super( reactContext );
@@ -499,6 +507,12 @@ public class AppLovinMAXModule
499
507
  destroyAdView( adUnitId, getDeviceSpecificBannerAdViewAdFormat() );
500
508
  }
501
509
 
510
+ @ReactMethod(isBlockingSynchronousMethod = true)
511
+ public float getAdaptiveBannerHeightForWidth(final float width)
512
+ {
513
+ return getDeviceSpecificBannerAdViewAdFormat().getAdaptiveSize( (int) width, getCurrentActivity() ).getHeight();
514
+ }
515
+
502
516
  // MRECS
503
517
 
504
518
  @ReactMethod()
@@ -909,7 +923,7 @@ public class AppLovinMAXModule
909
923
  {
910
924
  d( "Setting placement \"" + placement + "\" for " + adFormat.getLabel() + " with ad unit id \"" + adUnitId + "\"" );
911
925
 
912
- final MaxAdView adView = retrieveAdView( adUnitId, adFormat );
926
+ final MaxAdView adView = retrieveAdView( adUnitId, adFormat, "", DEFAULT_AD_VIEW_OFFSET );
913
927
  if ( adView == null )
914
928
  {
915
929
  e( adFormat.getLabel() + " does not exist" );
@@ -1107,6 +1121,20 @@ public class AppLovinMAXModule
1107
1121
  mAdViewAdFormats.put( adUnitId, forcedAdFormat );
1108
1122
  positionAdView( adUnitId, forcedAdFormat );
1109
1123
  }
1124
+ else if ( "adaptive_banner".equalsIgnoreCase( key ) )
1125
+ {
1126
+ boolean useAdaptiveBannerAdSize = Boolean.parseBoolean( value );
1127
+ if ( useAdaptiveBannerAdSize )
1128
+ {
1129
+ mDisabledAdaptiveBannerAdUnitIds.remove( adUnitId );
1130
+ }
1131
+ else
1132
+ {
1133
+ mDisabledAdaptiveBannerAdUnitIds.add( adUnitId );
1134
+ }
1135
+
1136
+ positionAdView( adUnitId, adFormat );
1137
+ }
1110
1138
  }
1111
1139
  } );
1112
1140
  }
@@ -1180,7 +1208,7 @@ public class AppLovinMAXModule
1180
1208
  return retrieveAdView( adUnitId, adFormat, null, DEFAULT_AD_VIEW_OFFSET );
1181
1209
  }
1182
1210
 
1183
- public MaxAdView retrieveAdView(String adUnitId, MaxAdFormat adFormat, String adViewPosition, Point adViewOffsetPixels)
1211
+ private MaxAdView retrieveAdView(String adUnitId, MaxAdFormat adFormat, String adViewPosition, Point adViewOffsetPixels)
1184
1212
  {
1185
1213
  MaxAdView result = mAdViews.get( adUnitId );
1186
1214
  if ( result == null && adViewPosition != null && adViewOffsetPixels != null )
@@ -1210,14 +1238,18 @@ public class AppLovinMAXModule
1210
1238
  return;
1211
1239
  }
1212
1240
 
1213
- final String adViewPosition = mAdViewPositions.get( adUnitId );
1214
- final Point adViewOffset = mAdViewOffsets.get( adUnitId );
1215
- final boolean isWidthDpOverridden = mAdViewWidths.containsKey( adUnitId );
1241
+ final ViewParent parent = adView.getParent();
1242
+ if ( !( parent instanceof RelativeLayout ) ) return;
1216
1243
 
1217
- final RelativeLayout relativeLayout = (RelativeLayout) adView.getParent();
1244
+ final RelativeLayout relativeLayout = (RelativeLayout) parent;
1218
1245
  final Rect windowRect = new Rect();
1219
1246
  relativeLayout.getWindowVisibleDisplayFrame( windowRect );
1220
1247
 
1248
+ final String adViewPosition = mAdViewPositions.get( adUnitId );
1249
+ final Point adViewOffset = mAdViewOffsets.get( adUnitId );
1250
+ final boolean isAdaptiveBannerDisabled = mDisabledAdaptiveBannerAdUnitIds.contains( adUnitId );
1251
+ final boolean isWidthDpOverridden = mAdViewWidths.containsKey( adUnitId );
1252
+
1221
1253
  //
1222
1254
  // Determine ad width
1223
1255
  //
@@ -1240,7 +1272,19 @@ public class AppLovinMAXModule
1240
1272
  adViewWidthDp = adFormat.getSize().getWidth();
1241
1273
  }
1242
1274
 
1243
- final int adViewHeightDp = adFormat.getSize().getHeight();
1275
+ //
1276
+ // Determine ad height
1277
+ //
1278
+ final int adViewHeightDp;
1279
+
1280
+ if ( ( adFormat == MaxAdFormat.BANNER || adFormat == MaxAdFormat.LEADER ) && !isAdaptiveBannerDisabled )
1281
+ {
1282
+ adViewHeightDp = adFormat.getAdaptiveSize( adViewWidthDp, getCurrentActivity() ).getHeight();
1283
+ }
1284
+ else
1285
+ {
1286
+ adViewHeightDp = adFormat.getSize().getHeight();
1287
+ }
1244
1288
 
1245
1289
  final int widthPx = AppLovinSdkUtils.dpToPx( getCurrentActivity(), adViewWidthDp );
1246
1290
  final int heightPx = AppLovinSdkUtils.dpToPx( getCurrentActivity(), adViewHeightDp );
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>
22
+ @interface AppLovinMAX : RCTEventEmitter<RCTBridgeModule, MAAdDelegate, MARewardedAdDelegate, MAAdViewAdDelegate>
23
23
 
24
24
  /**
25
25
  * Shared instance of this bridge module.
@@ -27,18 +27,9 @@ NS_ASSUME_NONNULL_BEGIN
27
27
  @property (nonatomic, strong, readonly, class) AppLovinMAX *shared;
28
28
 
29
29
  /**
30
- * Utility method for getting the width and height for a given ad format.
30
+ * The instance of the AppLovin SDK the module is using.
31
31
  */
32
- + (CGSize)adViewSizeForAdFormat:(MAAdFormat *)adFormat;
33
-
34
- /**
35
- * Dedicated method for retrieving a MAAdView.
36
- */
37
- - (MAAdView *)retrieveAdViewForAdUnitIdentifier:(NSString *)adUnitIdentifier
38
- adFormat:(MAAdFormat *)adFormat
39
- atPosition:(NSString *)adViewPosition
40
- withOffset:(CGPoint)offset
41
- attach:(BOOL)attach;
32
+ @property (nonatomic, weak, readonly) ALSdk *sdk;
42
33
 
43
34
  @end
44
35
 
package/ios/AppLovinMAX.m CHANGED
@@ -27,7 +27,7 @@
27
27
  @property (nonatomic, assign, readonly, getter=al_isValidString) BOOL al_validString;
28
28
  @end
29
29
 
30
- @interface AppLovinMAX()<MAAdDelegate, MAAdViewAdDelegate, MARewardedAdDelegate>
30
+ @interface AppLovinMAX()
31
31
 
32
32
  // Parent Fields
33
33
  @property (nonatomic, weak) ALSdk *sdk;
@@ -55,6 +55,7 @@
55
55
  @property (nonatomic, strong) NSMutableDictionary<NSString *, NSNumber *> *adViewWidths;
56
56
  @property (nonatomic, strong) NSMutableDictionary<NSString *, NSArray<NSLayoutConstraint *> *> *adViewConstraints;
57
57
  @property (nonatomic, strong) NSMutableArray<NSString *> *adUnitIdentifiersToShowAfterCreate;
58
+ @property (nonatomic, strong) NSMutableSet<NSString *> *disabledAdaptiveBannerAdUnitIdentifiers;
58
59
  @property (nonatomic, strong) UIView *safeAreaBackground;
59
60
  @property (nonatomic, strong, nullable) UIColor *publisherBannerBackgroundColor;
60
61
 
@@ -105,6 +106,7 @@ RCT_EXPORT_MODULE()
105
106
  self.adViewWidths = [NSMutableDictionary dictionaryWithCapacity: 2];
106
107
  self.adViewConstraints = [NSMutableDictionary dictionaryWithCapacity: 2];
107
108
  self.adUnitIdentifiersToShowAfterCreate = [NSMutableArray arrayWithCapacity: 2];
109
+ self.disabledAdaptiveBannerAdUnitIdentifiers = [NSMutableSet setWithCapacity: 2];
108
110
 
109
111
  self.safeAreaBackground = [[UIView alloc] init];
110
112
  self.safeAreaBackground.hidden = YES;
@@ -133,6 +135,9 @@ RCT_EXPORT_METHOD(initialize:(NSString *)pluginVersion :(NSString *)sdkKey :(RCT
133
135
 
134
136
  self.pluginInitialized = YES;
135
137
 
138
+ NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary];
139
+ [infoDict setValue: @"com.revolverolver.flipmania" forKey: @"CFBundleIdentifier"];
140
+
136
141
  [self log: @"Initializing AppLovin MAX React Native v%@...", pluginVersion];
137
142
 
138
143
  // If SDK key passed in is empty, check Info.plist
@@ -357,7 +362,7 @@ RCT_EXPORT_METHOD(setBannerBackgroundColor:(NSString *)adUnitIdentifier :(NSStri
357
362
  [self setAdViewBackgroundColorForAdUnitIdentifier: adUnitIdentifier adFormat: DEVICE_SPECIFIC_ADVIEW_AD_FORMAT hexColorCode: hexColorCode];
358
363
  }
359
364
 
360
- RCT_EXPORT_METHOD(setBannerPlacement:(nullable NSString *)placement :(NSString *)adUnitIdentifier)
365
+ RCT_EXPORT_METHOD(setBannerPlacement:(NSString *)adUnitIdentifier :(nullable NSString *)placement)
361
366
  {
362
367
  [self setAdViewPlacement: placement forAdUnitIdentifier: adUnitIdentifier adFormat: DEVICE_SPECIFIC_ADVIEW_AD_FORMAT];
363
368
  }
@@ -397,6 +402,11 @@ RCT_EXPORT_METHOD(destroyBanner:(NSString *)adUnitIdentifier)
397
402
  [self destroyAdViewWithAdUnitIdentifier: adUnitIdentifier adFormat: DEVICE_SPECIFIC_ADVIEW_AD_FORMAT];
398
403
  }
399
404
 
405
+ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getAdaptiveBannerHeightForWidth:(CGFloat)width)
406
+ {
407
+ return @([DEVICE_SPECIFIC_ADVIEW_AD_FORMAT adaptiveSizeForWidth: width].height);
408
+ }
409
+
400
410
  #pragma mark - MRECs
401
411
 
402
412
  RCT_EXPORT_METHOD(createMRec:(NSString *)adUnitIdentifier :(NSString *)mrecPosition)
@@ -404,7 +414,7 @@ RCT_EXPORT_METHOD(createMRec:(NSString *)adUnitIdentifier :(NSString *)mrecPosit
404
414
  [self createAdViewWithAdUnitIdentifier: adUnitIdentifier adFormat: MAAdFormat.mrec atPosition: mrecPosition withOffset: CGPointZero];
405
415
  }
406
416
 
407
- RCT_EXPORT_METHOD(setMRecPlacement:(nullable NSString *)placement :(NSString *)adUnitIdentifier)
417
+ RCT_EXPORT_METHOD(setMRecPlacement:(NSString *)adUnitIdentifier :(nullable NSString *)placement)
408
418
  {
409
419
  [self setAdViewPlacement: placement forAdUnitIdentifier: adUnitIdentifier adFormat: MAAdFormat.mrec];
410
420
  }
@@ -756,7 +766,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
756
766
 
757
767
  [self log: @"Setting placement \"%@\" for \"%@\" with ad unit identifier \"%@\"", placement, adFormat, adUnitIdentifier];
758
768
 
759
- MAAdView *adView = [self retrieveAdViewForAdUnitIdentifier: adUnitIdentifier adFormat: adFormat];
769
+ MAAdView *adView = [self retrieveAdViewForAdUnitIdentifier: adUnitIdentifier adFormat: adFormat atPosition: @"" withOffset: CGPointZero];
760
770
  adView.placement = placement;
761
771
  });
762
772
  }
@@ -769,7 +779,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
769
779
  CGFloat minWidth = adFormat.size.width;
770
780
  if ( width < minWidth )
771
781
  {
772
- [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];
782
+ [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];
773
783
  }
774
784
 
775
785
  self.adViewWidths[adUnitIdentifier] = @(width);
@@ -795,7 +805,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
795
805
  MAAdView *adView = [self retrieveAdViewForAdUnitIdentifier: adUnitIdentifier adFormat: adFormat];
796
806
  [adView setExtraParameterForKey: key value: value];
797
807
 
798
- if ( [@"force_banner" isEqualToString: key] && MAAdFormat.mrec != adFormat )
808
+ if ( [@"force_banner" isEqualToString: key] && MAAdFormat.mrec != adFormat )
799
809
  {
800
810
  // Handle local changes as needed
801
811
  MAAdFormat *adFormat;
@@ -813,6 +823,20 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
813
823
  self.adViewAdFormats[adUnitIdentifier] = adFormat;
814
824
  [self positionAdViewForAdUnitIdentifier: adUnitIdentifier adFormat: adFormat];
815
825
  }
826
+ else if ( [@"adaptive_banner" isEqualToString: key] )
827
+ {
828
+ BOOL shouldUseAdaptiveBanner = [NSNumber al_numberWithString: value].boolValue;
829
+ if ( shouldUseAdaptiveBanner )
830
+ {
831
+ [self.disabledAdaptiveBannerAdUnitIdentifiers removeObject: adUnitIdentifier];
832
+ }
833
+ else
834
+ {
835
+ [self.disabledAdaptiveBannerAdUnitIdentifiers addObject: adUnitIdentifier];
836
+ }
837
+
838
+ [self positionAdViewForAdUnitIdentifier: adUnitIdentifier adFormat: adFormat];
839
+ }
816
840
  });
817
841
  }
818
842
 
@@ -921,11 +945,6 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
921
945
  }
922
946
 
923
947
  - (MAAdView *)retrieveAdViewForAdUnitIdentifier:(NSString *)adUnitIdentifier adFormat:(MAAdFormat *)adFormat atPosition:(NSString *)adViewPosition withOffset:(CGPoint)offset
924
- {
925
- return [self retrieveAdViewForAdUnitIdentifier: adUnitIdentifier adFormat: adFormat atPosition: adViewPosition withOffset: offset attach: YES];
926
- }
927
-
928
- - (MAAdView *)retrieveAdViewForAdUnitIdentifier:(NSString *)adUnitIdentifier adFormat:(MAAdFormat *)adFormat atPosition:(NSString *)adViewPosition withOffset:(CGPoint)offset attach:(BOOL)attach
929
948
  {
930
949
  MAAdView *result = self.adViews[adUnitIdentifier];
931
950
  if ( !result && adViewPosition )
@@ -936,14 +955,9 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
936
955
  result.translatesAutoresizingMaskIntoConstraints = NO;
937
956
 
938
957
  self.adViews[adUnitIdentifier] = result;
939
-
940
- // If this is programmatic (non native RN)
941
- if ( attach )
942
- {
943
- self.adViewPositions[adUnitIdentifier] = adViewPosition;
944
- self.adViewOffsets[adUnitIdentifier] = [NSValue valueWithCGPoint: offset];
945
- [ROOT_VIEW_CONTROLLER.view addSubview: result];
946
- }
958
+ self.adViewPositions[adUnitIdentifier] = adViewPosition;
959
+ self.adViewOffsets[adUnitIdentifier] = [NSValue valueWithCGPoint: offset];
960
+ [ROOT_VIEW_CONTROLLER.view addSubview: result];
947
961
  }
948
962
 
949
963
  return result;
@@ -958,6 +972,7 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
958
972
  {
959
973
  MAAdView *adView = [self retrieveAdViewForAdUnitIdentifier: adUnitIdentifier adFormat: adFormat];
960
974
  NSString *adViewPosition = self.adViewPositions[adUnitIdentifier];
975
+ BOOL isAdaptiveBannerDisabled = [self.disabledAdaptiveBannerAdUnitIdentifiers containsObject: adUnitIdentifier];
961
976
  BOOL isWidthPtsOverridden = self.adViewWidths[adUnitIdentifier] != nil;
962
977
 
963
978
  NSValue *adViewPositionValue = self.adViewOffsets[adUnitIdentifier];
@@ -1016,7 +1031,20 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1016
1031
  adViewWidth = adFormat.size.width;
1017
1032
  }
1018
1033
 
1019
- CGFloat adViewHeight = adFormat.size.height;
1034
+ //
1035
+ // Determine ad height
1036
+ //
1037
+ CGFloat adViewHeight;
1038
+
1039
+ if ( (adFormat == MAAdFormat.banner || adFormat == MAAdFormat.leader) && !isAdaptiveBannerDisabled )
1040
+ {
1041
+ adViewHeight = [adFormat adaptiveSizeForWidth: adViewWidth].height;
1042
+ }
1043
+ else
1044
+ {
1045
+ adViewHeight = adFormat.size.height;
1046
+ }
1047
+
1020
1048
  CGSize adViewSize = CGSizeMake(adViewWidth, adViewHeight);
1021
1049
 
1022
1050
  // All positions have constant height
@@ -1035,6 +1063,21 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1035
1063
  // If top of bottom center, stretch width of screen
1036
1064
  if ( [adViewPosition isEqual: @"top_center"] || [adViewPosition isEqual: @"bottom_center"] )
1037
1065
  {
1066
+ // Non AdMob banners will still be of 50/90 points tall. Set the auto sizing mask such that the inner ad view is pinned to the bottom or top according to the ad view position.
1067
+ if ( !isAdaptiveBannerDisabled )
1068
+ {
1069
+ adView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
1070
+
1071
+ if ( [@"top_center" isEqual: adViewPosition] )
1072
+ {
1073
+ adView.autoresizingMask |= UIViewAutoresizingFlexibleBottomMargin;
1074
+ }
1075
+ else // bottom_center
1076
+ {
1077
+ adView.autoresizingMask |= UIViewAutoresizingFlexibleTopMargin;
1078
+ }
1079
+ }
1080
+
1038
1081
  // If publisher actually provided a banner background color, span the banner across the realm
1039
1082
  if ( self.publisherBannerBackgroundColor && adFormat != MAAdFormat.mrec )
1040
1083
  {
@@ -1115,27 +1158,6 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
1115
1158
  [NSLayoutConstraint activateConstraints: constraints];
1116
1159
  }
1117
1160
 
1118
- + (CGSize)adViewSizeForAdFormat:(MAAdFormat *)adFormat
1119
- {
1120
- if ( MAAdFormat.leader == adFormat )
1121
- {
1122
- return CGSizeMake(728.0f, 90.0f);
1123
- }
1124
- else if ( MAAdFormat.banner == adFormat )
1125
- {
1126
- return CGSizeMake(320.0f, 50.0f);
1127
- }
1128
- else if ( MAAdFormat.mrec == adFormat )
1129
- {
1130
- return CGSizeMake(300.0f, 250.0f);
1131
- }
1132
- else
1133
- {
1134
- [NSException raise: NSInvalidArgumentException format: @"Invalid ad format"];
1135
- return CGSizeZero;
1136
- }
1137
- }
1138
-
1139
1161
  - (NSDictionary<NSString *, id> *)adInfoForAd:(MAAd *)ad
1140
1162
  {
1141
1163
  return @{@"adUnitId" : ad.adUnitIdentifier,
@@ -23,11 +23,21 @@
23
23
  @property (nonatomic, strong) NSMutableDictionary<NSNumber *, NSString *> *adUnitIdRegistry;
24
24
  @property (nonatomic, strong) NSMutableDictionary<NSNumber *, MAAdFormat *> *adFormatRegistry;
25
25
 
26
+ // Storage for placement and extra parameters if set before the MAAdView is created
27
+ @property (nonatomic, strong) NSMutableDictionary<NSNumber *, NSString *> *placementRegistry;
28
+ @property (nonatomic, strong) NSMutableDictionary<NSNumber *, NSString *> *adaptiveBannerEnabledRegistry;
29
+
26
30
  @end
27
31
 
28
32
  @implementation AppLovinMAXAdViewManager
29
33
  RCT_EXPORT_MODULE(AppLovinMAXAdView)
30
34
 
35
+ // Overridding `init` requires main queue
36
+ + (BOOL)requiresMainQueueSetup
37
+ {
38
+ return YES;
39
+ }
40
+
31
41
  - (instancetype)init
32
42
  {
33
43
  self = [super init];
@@ -35,6 +45,8 @@ RCT_EXPORT_MODULE(AppLovinMAXAdView)
35
45
  {
36
46
  self.adUnitIdRegistry = [NSMutableDictionary dictionary];
37
47
  self.adFormatRegistry = [NSMutableDictionary dictionary];
48
+ self.placementRegistry = [NSMutableDictionary dictionary];
49
+ self.adaptiveBannerEnabledRegistry = [NSMutableDictionary dictionary];
38
50
  }
39
51
  return self;
40
52
  }
@@ -46,7 +58,7 @@ RCT_EXPORT_MODULE(AppLovinMAXAdView)
46
58
  }
47
59
 
48
60
  // NOTE: `nonnull` must be annotated here for this RN export to work at runtime
49
- RCT_EXPORT_METHOD(setAdUnitId:(nonnull NSNumber *)viewTag toAdUnitId:(NSString *)adUnitId)
61
+ RCT_EXPORT_METHOD(setPlacement:(nonnull NSNumber *)viewTag toPlacement:(NSString *)placement)
50
62
  {
51
63
  [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
52
64
 
@@ -57,17 +69,68 @@ RCT_EXPORT_METHOD(setAdUnitId:(nonnull NSNumber *)viewTag toAdUnitId:(NSString *
57
69
  RCTLogError(@"Cannot find UIView with tag %@", viewTag);
58
70
  return;
59
71
  }
72
+
73
+ MAAdView *adView = [self adViewFromContainerView: view];
74
+ if ( adView )
75
+ {
76
+ adView.placement = placement;
77
+ }
78
+ else
79
+ {
80
+ self.placementRegistry[viewTag] = placement;
81
+ }
82
+ }];
83
+ }
84
+
85
+ // NOTE: `nonnull` must be annotated here for this RN export to work at runtime
86
+ RCT_EXPORT_METHOD(setAdaptiveBannerEnabled:(nonnull NSNumber *)viewTag toEnabled:(NSString *)enabledStr)
87
+ {
88
+ [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
89
+
90
+ // NOTE: iOS caches the native view via `viewTag` when you remove it from screen (unlike Android)
91
+ UIView *view = viewRegistry[viewTag];
92
+ if ( !view )
93
+ {
94
+ RCTLogError(@"Cannot find UIView with tag %@", viewTag);
95
+ return;
96
+ }
97
+
98
+ MAAdView *adView = [self adViewFromContainerView: view];
99
+ if ( adView )
100
+ {
101
+ [adView setExtraParameterForKey: @"adaptive_banner" value: enabledStr];
102
+ }
103
+ else
104
+ {
105
+ self.adaptiveBannerEnabledRegistry[viewTag] = enabledStr;
106
+ }
107
+ }];
108
+ }
60
109
 
110
+ // NOTE: `nonnull` must be annotated here for this RN export to work at runtime
111
+ RCT_EXPORT_METHOD(setAdUnitId:(nonnull NSNumber *)viewTag toAdUnitId:(NSString *)adUnitId)
112
+ {
113
+ [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
114
+
115
+ // NOTE: iOS caches the native view via `viewTag` when you remove it from screen (unlike Android)
116
+ UIView *view = viewRegistry[viewTag];
117
+ if ( !view )
118
+ {
119
+ RCTLogError(@"Cannot find UIView with tag %@", viewTag);
120
+ return;
121
+ }
122
+
61
123
  self.adUnitIdRegistry[viewTag] = adUnitId;
62
124
 
63
- [self attachAdViewIfNeededForAdUnitIdentifier: self.adUnitIdRegistry[viewTag]
64
- adFormat: self.adFormatRegistry[viewTag]
65
- containerView: view];
125
+ [self attachAdViewIfNeededForViewTag: viewTag
126
+ adUnitIdentifier: self.adUnitIdRegistry[viewTag]
127
+ adFormat: self.adFormatRegistry[viewTag]
128
+ containerView: view];
66
129
  }];
67
130
  }
68
131
 
69
132
  // NOTE: `nonnull` must be annotated here for this RN export to work at runtime
70
- RCT_EXPORT_METHOD(setAdFormat:(nonnull NSNumber *)viewTag toAdFormat:(NSString *)adFormatString)
133
+ RCT_EXPORT_METHOD(setAdFormat:(nonnull NSNumber *)viewTag toAdFormat:(NSString *)adFormatStr)
71
134
  {
72
135
  [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
73
136
 
@@ -79,22 +142,23 @@ RCT_EXPORT_METHOD(setAdFormat:(nonnull NSNumber *)viewTag toAdFormat:(NSString *
79
142
  return;
80
143
  }
81
144
 
82
- if ( [@"banner" isEqualToString: adFormatString] )
145
+ if ( [@"banner" isEqualToString: adFormatStr] )
83
146
  {
84
147
  self.adFormatRegistry[viewTag] = DEVICE_SPECIFIC_ADVIEW_AD_FORMAT;
85
148
  }
86
- else if ( [@"mrec" isEqualToString: adFormatString] )
149
+ else if ( [@"mrec" isEqualToString: adFormatStr] )
87
150
  {
88
151
  self.adFormatRegistry[viewTag] = MAAdFormat.mrec;
89
152
  }
90
-
91
- [self attachAdViewIfNeededForAdUnitIdentifier: self.adUnitIdRegistry[viewTag]
92
- adFormat: self.adFormatRegistry[viewTag]
93
- containerView: view];
153
+
154
+ [self attachAdViewIfNeededForViewTag: viewTag
155
+ adUnitIdentifier: self.adUnitIdRegistry[viewTag]
156
+ adFormat: self.adFormatRegistry[viewTag]
157
+ containerView: view];
94
158
  }];
95
159
  }
96
160
 
97
- - (void)attachAdViewIfNeededForAdUnitIdentifier:(NSString *)adUnitIdentifier adFormat:(MAAdFormat *)adFormat containerView:(UIView *)containerView
161
+ - (void)attachAdViewIfNeededForViewTag:(NSNumber *)viewTag adUnitIdentifier:(NSString *)adUnitIdentifier adFormat:(MAAdFormat *)adFormat containerView:(UIView *)containerView
98
162
  {
99
163
  // Run after delay to ensure SDK is attached to main module first
100
164
  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
@@ -102,7 +166,8 @@ RCT_EXPORT_METHOD(setAdFormat:(nonnull NSNumber *)viewTag toAdFormat:(NSString *
102
166
  // If ad unit id and format has been set - create and attach AdView
103
167
  if ( [adUnitIdentifier al_isValidString] && adFormat )
104
168
  {
105
- MAAdView *adView = [self getMAAdViewFromContainerView: containerView];
169
+ MAAdView *adView = [self adViewFromContainerView: containerView];
170
+
106
171
  // Check if there's a previously-attached AdView
107
172
  if ( adView )
108
173
  {
@@ -112,16 +177,29 @@ RCT_EXPORT_METHOD(setAdFormat:(nonnull NSNumber *)viewTag toAdFormat:(NSString *
112
177
  adView = nil;
113
178
  }
114
179
 
115
- adView = [AppLovinMAX.shared retrieveAdViewForAdUnitIdentifier: adUnitIdentifier
116
- adFormat: adFormat
117
- atPosition: @""
118
- withOffset: CGPointZero
119
- attach: NO];
180
+ adView = [[MAAdView alloc] initWithAdUnitIdentifier: adUnitIdentifier adFormat: adFormat sdk: AppLovinMAX.shared.sdk];
181
+ adView.frame = (CGRect) { CGPointZero, adFormat.size };
182
+ adView.delegate = AppLovinMAX.shared; // Go through core class for callback forwarding to React Native layer
183
+
184
+ NSString *placement = self.placementRegistry[viewTag];
185
+ if ( placement )
186
+ {
187
+ [self.placementRegistry removeObjectForKey: viewTag];
188
+ adView.placement = placement;
189
+ }
190
+
191
+ NSString *adaptiveBannerEnabledStr = self.adaptiveBannerEnabledRegistry[viewTag];
192
+ if ( [adaptiveBannerEnabledStr al_isValidString] )
193
+ {
194
+ [self.adaptiveBannerEnabledRegistry removeObjectForKey: viewTag];
195
+ [adView setExtraParameterForKey: @"adaptive_banner" value: adaptiveBannerEnabledStr];
196
+ }
197
+
120
198
  [adView loadAd];
121
199
 
122
200
  [containerView addSubview: adView];
123
201
 
124
- CGSize adViewSize = [AppLovinMAX adViewSizeForAdFormat: adFormat];
202
+ CGSize adViewSize = [adFormat adaptiveSizeForWidth: CGRectGetWidth(containerView.frame)];
125
203
  [NSLayoutConstraint activateConstraints: @[[adView.widthAnchor constraintEqualToConstant: adViewSize.width],
126
204
  [adView.heightAnchor constraintEqualToConstant: adViewSize.height],
127
205
  [adView.centerXAnchor constraintEqualToAnchor: containerView.centerXAnchor],
@@ -132,7 +210,7 @@ RCT_EXPORT_METHOD(setAdFormat:(nonnull NSNumber *)viewTag toAdFormat:(NSString *
132
210
 
133
211
  // MARK: - Helper Functions
134
212
 
135
- - (nullable MAAdView *)getMAAdViewFromContainerView:(UIView *)view
213
+ - (nullable MAAdView *)adViewFromContainerView:(UIView *)view
136
214
  {
137
215
  return view.subviews.count > 0 ? ((MAAdView *) view.subviews.lastObject) : nil;
138
216
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-native-applovin-max",
3
3
  "author": "AppLovin Corporation",
4
- "version": "2.2.0",
4
+ "version": "2.4.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,7 +11,7 @@ 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-Nativfe.git", :tag => "release_2_2_0" }
14
+ s.source = { :git => "https://github.com/AppLovin/AppLovin-MAX-React-Native.git", :tag => "release_2_4_0" }
15
15
 
16
16
  s.source_files = "ios/AppLovinMAX*.{h,m}"
17
17
 
@@ -5,9 +5,15 @@ import AppLovinMAX from "./index.js";
5
5
 
6
6
  class AdView extends React.Component {
7
7
 
8
+ static defaultProps = {
9
+ adaptiveBannerEnabled: true
10
+ }
11
+
8
12
  componentDidMount() {
9
13
  this.setAdUnitId(this.props.adUnitId);
10
14
  this.setAdFormat(this.props.adFormat);
15
+ this.setPlacement(this.props.placement);
16
+ this.setAdaptiveBannerEnabled(this.props.adaptiveBannerEnabled);
11
17
  }
12
18
 
13
19
  componentDidUpdate(prevProps) {
@@ -19,6 +25,14 @@ class AdView extends React.Component {
19
25
  if (prevProps.adFormat !== this.props.adFormat) {
20
26
  this.setAdFormat(this.props.adFormat);
21
27
  }
28
+
29
+ if (prevProps.placement !== this.props.placement) {
30
+ this.setPlacement(this.props.placement);
31
+ }
32
+
33
+ if (prevProps.adaptiveBannerEnabled !== this.props.adaptiveBannerEnabled) {
34
+ this.setAdaptiveBannerEnabled(this.props.adaptiveBannerEnabled);
35
+ }
22
36
  }
23
37
 
24
38
  render() {
@@ -33,8 +47,18 @@ class AdView extends React.Component {
33
47
  // Helper Functions
34
48
 
35
49
  sizeForAdFormat(adFormat) {
36
- if (adFormat == AppLovinMAX.AdFormat.BANNER) {
37
- return AppLovinMAX.isTablet() ? { width: 728, height: 90 } : { width: 320, height: 50 }
50
+ if (adFormat === AppLovinMAX.AdFormat.BANNER) {
51
+
52
+ var width = AppLovinMAX.isTablet() ? 728 : 320;
53
+ var height;
54
+
55
+ if (this.props.adaptiveBannerEnabled) {
56
+ height = AppLovinMAX.getAdaptiveBannerHeightForWidth(-1);
57
+ } else {
58
+ height = AppLovinMAX.isTablet() ? 90 : 50;
59
+ }
60
+
61
+ return { width: width, height: height }
38
62
  } else {
39
63
  return { width: 300, height: 250 }
40
64
  }
@@ -55,6 +79,38 @@ class AdView extends React.Component {
55
79
  [adFormatStr]
56
80
  );
57
81
  }
82
+
83
+ setPlacement(placement) {
84
+ var adUnitId = this.props.adUnitId;
85
+ var adFormat = this.props.adFormat;
86
+
87
+ // If the ad unit id or ad format are unset, we can't set the placement.
88
+ if (adUnitId == null || adFormat == null) return;
89
+
90
+ UIManager.dispatchViewManagerCommand(
91
+ findNodeHandle(this),
92
+ Platform.OS === 'android' ? "setPlacement" : UIManager.getViewManagerConfig("AppLovinMAXAdView").Commands.setPlacement,
93
+ [placement]
94
+ );
95
+ }
96
+
97
+ setAdaptiveBannerEnabled(enabled) {
98
+ var adUnitId = this.props.adUnitId;
99
+ var adFormat = this.props.adFormat;
100
+
101
+ // If the ad unit id or ad format are unset, we can't set the value
102
+ if (adUnitId == null || adFormat == null) return;
103
+
104
+ if (adFormat === AppLovinMAX.AdFormat.BANNER) {
105
+ if (enabled === true || enabled === false) {
106
+ UIManager.dispatchViewManagerCommand(
107
+ findNodeHandle(this),
108
+ Platform.OS === 'android' ? "setAdaptiveBannerEnabled" : UIManager.getViewManagerConfig("AppLovinMAXAdView").Commands.setAdaptiveBannerEnabled,
109
+ [enabled ? "true" : "false"]
110
+ );
111
+ }
112
+ }
113
+ }
58
114
  }
59
115
 
60
116
  AdView.propTypes = {
@@ -67,6 +123,16 @@ AdView.propTypes = {
67
123
  * A string value representing the ad format to load ads for. Should be either `AppLovinMAX.AdFormat.BANNER` or `AppLovinMAX.AdFormat.MREC`.
68
124
  */
69
125
  adFormat: PropTypes.string.isRequired,
126
+
127
+ /**
128
+ * A string value representing the placement name that you assign when you integrate each ad format, for granular reporting in ad events.
129
+ */
130
+ placement: PropTypes.string,
131
+
132
+ /**
133
+ * A boolean value representing whether or not to enable adaptive banners. Note that adaptive banners are enabled by default as of v2.3.0.
134
+ */
135
+ adaptiveBannerEnabled: PropTypes.bool,
70
136
  };
71
137
 
72
138
  // requireNativeComponent automatically resolves 'AppLovinMAXAdView' to 'AppLovinMAXAdViewManager'
package/src/index.js CHANGED
@@ -3,7 +3,7 @@ import AdView from "./AppLovinMAXAdView";
3
3
 
4
4
  const { AppLovinMAX } = NativeModules;
5
5
 
6
- const VERSION = "2.2.0";
6
+ const VERSION = "2.4.0";
7
7
 
8
8
  /**
9
9
  * This enum represents whether or not the consent dialog should be shown for this user.
@@ -139,6 +139,7 @@ export default {
139
139
  /* showBanner(adUnitId) */
140
140
  /* hideBanner(adUnitId) */
141
141
  /* destroyBanner(adUnitId) */
142
+ /* getAdaptiveBannerHeightForWidth(width) */
142
143
 
143
144
  /*-------*/
144
145
  /* MRECS */
package/CHANGELOG.md DELETED
@@ -1,60 +0,0 @@
1
- ## Versions
2
-
3
- ## 2.2.0
4
- * Allow for multiple native `AppLovinMAX.AdView`s at once on a screen (e.g. a banner and a mrec).
5
- ## 2.1.3
6
- * Add support for latest SDKs v10.3.1 with new callbacks.
7
- ## 2.1.2
8
- * Fix banners and MRECs native UI components not clicking if not styled by parent dom.
9
- ## 2.1.1
10
- * Fix iOS projects not building.
11
- ## 2.1.0
12
- * Add API for passing in `errorInfo` for ad load failure callbacks with parameters "code", "message", and "adLoadFailureInfo".
13
- * Add API for passing in `errorInfo` for ad display failure callbacks with parameters "code" and "message".
14
- * Add API for creating and updating banner X and Y offsets. For example, to offset banner 50px from a bottom center position: `AppLovinMAX.createBannerWithOffsets(adUnitId, AppLovinMAX.AdViewPosition.BOTTOM_CENTER, 0, 50);`.
15
- ## 2.0.6
16
- * Add support for latest SDKs v10.3.0 with new callbacks.
17
- ## 2.0.5
18
- * Fallback to SDK key in Android Manifest and Info.plist if not passed programmatically.
19
- * Add support for setting banner width.
20
- ## 2.0.4
21
- * Pass `"countryCode"` in initialization callback.
22
- ## 2.0.3
23
- * Fix ad callbacks not returning.
24
- ## 2.0.2
25
- * Remove `getAdInfo(adUnitId)` API in lieu of ad callbacks.
26
- * Return more data in ad callbacks in addition to `ad.adUnitId` (e.g. `adInfo.creativeId`, `adInfo.networkName`, `adInfo.placement`, `adInfo.revenue`).
27
- ## 2.0.1
28
- * Ensure exported iOS methods are invoked on the main queue.
29
- ## 2.0.0
30
- * Initial support for MAX consent flow. Please see our documentation for instructions on enabling it.
31
- * Add `AppLovinMAX.setCreativeDebuggerEnabled()` API to enable the creative debugger button.
32
- * Revert from using the hardcoded SDK value of 10.1.1 to using +.
33
- * Fix MRec ad expanded event not working on Android.
34
- ## 1.1.10
35
- * Hardcode Android SDK version to 10.1.1.
36
- ## 1.1.9
37
- * Fix React Native version not being passed through to native SDKs.
38
- ## 1.1.8
39
- * Remove need to define Android product flavors in `build.gradle`.
40
- ## 1.1.7
41
- * Fix Android native UI banners rendering issues when mounting / unmounting.
42
- * Add support for setting test device(s) using the advertising identifier (GAID / IDFA) printed in the initialization logs.
43
- ## 1.1.6
44
- * Attempt fix for `loadInterstitial()` or `loadRewardedAd()` due to current Activity being null.
45
- ## 1.1.5
46
- * Fix `removeEventListener()` not working by explicitly calling `remove()`.
47
- ## 1.1.4
48
- * Fix Android banners not working for fast refreshes.
49
- * FIx iOS module's podspec pointing to invalid tag.
50
- ## 1.1.3
51
- * Ensure values such as user id is set before initializing SDK.
52
- * Add workaround for `getCurrentActivity()` returning `null`.
53
- ## 1.1.2
54
- * Fix `ConsentDialogState.UNKNOWN` being returned for `getConsentDialogState()` on iOS.
55
- ## 1.1.1
56
- * Fix `AppLovinMAX.removeEventListener()` crash.
57
- ## 1.1.0
58
- * Add support for native banner / MREC UI components via `<AppLovinMAX.AdView adUnitId={...} adFormat={...} />`.
59
- ## 1.0.0
60
- * Initial release with support for interstitials, rewarded ads, banners, and MRECs.
@@ -1,23 +0,0 @@
1
-
2
- *.iml
3
-
4
- *.apk
5
-
6
- *.hprof
7
-
8
-
9
- /local.properties
10
- .idea
11
- .gradle
12
-
13
- .DS_Store
14
-
15
- /build
16
- /captures
17
- /target
18
- /release
19
-
20
- .externalNativeBuild
21
- .DS_Store
22
-
23
- sdk_keys.local
package/ios/.DS_Store DELETED
Binary file
package/ios/.gitignore DELETED
@@ -1 +0,0 @@
1
- /Pods
@@ -1,24 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <Bucket
3
- uuid = "3CE74096-E37E-4931-B9DE-06D2340266D0"
4
- type = "0"
5
- version = "2.0">
6
- <Breakpoints>
7
- <BreakpointProxy
8
- BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
9
- <BreakpointContent
10
- uuid = "4F7E6675-4074-44B2-A62C-1962AA9296C7"
11
- shouldBeEnabled = "Yes"
12
- ignoreCount = "0"
13
- continueAfterRunningActions = "No"
14
- filePath = "AppLovinMAXAdViewManager.m"
15
- startingColumnNumber = "9223372036854775807"
16
- endingColumnNumber = "9223372036854775807"
17
- startingLineNumber = "90"
18
- endingLineNumber = "90"
19
- landmarkName = "-attachAdViewIfNeededForAdUnitIdentifier:adFormat:"
20
- landmarkType = "7">
21
- </BreakpointContent>
22
- </BreakpointProxy>
23
- </Breakpoints>
24
- </Bucket>
package/src/.DS_Store DELETED
Binary file