react-native-applovin-max 3.3.1 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +3 -3
- package/android/gradle/wrapper/gradle-wrapper.properties +1 -1
- package/android/src/main/java/com/applovin/reactnative/AppLovinMAXModule.java +20 -3
- package/android/src/main/java/com/applovin/reactnative/AppLovinMAXNativeAdView.java +365 -0
- package/android/src/main/java/com/applovin/reactnative/AppLovinMAXNativeAdViewManager.java +148 -0
- package/android/src/main/java/com/applovin/reactnative/AppLovinMAXPackage.java +2 -1
- package/ios/AppLovinMAX.h +5 -0
- package/ios/AppLovinMAX.m +31 -3
- package/ios/AppLovinMAX.xcodeproj/project.pbxproj +14 -2
- package/ios/AppLovinMAX.xcworkspace/xcuserdata/thomasso.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/AppLovinMAXAdView.h +7 -0
- package/ios/AppLovinMAXAdView.m +7 -0
- package/ios/AppLovinMAXNativeAdView.h +27 -0
- package/ios/AppLovinMAXNativeAdView.m +308 -0
- package/ios/AppLovinMAXNativeAdViewManager.h +19 -0
- package/ios/AppLovinMAXNativeAdViewManager.m +60 -0
- package/ios/Podfile +1 -1
- package/ios/Podfile.lock +4 -4
- package/package.json +1 -1
- package/react-native-applovin-max.podspec +2 -2
- package/src/AppLovinMAXAdView.js +1 -1
- package/src/NativeAdComponents.js +156 -0
- package/src/NativeAdView.js +118 -0
- package/src/NativeAdViewProvider.js +19 -0
- package/src/index.js +3 -1
package/android/build.gradle
CHANGED
|
@@ -41,8 +41,8 @@ android {
|
|
|
41
41
|
defaultConfig {
|
|
42
42
|
minSdkVersion 16
|
|
43
43
|
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
|
|
44
|
-
versionCode
|
|
45
|
-
versionName "
|
|
44
|
+
versionCode 4000000
|
|
45
|
+
versionName "4.0.0"
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
flavorDimensions("default")
|
|
@@ -150,5 +150,5 @@ dependencies {
|
|
|
150
150
|
|
|
151
151
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
152
152
|
|
|
153
|
-
implementation 'com.applovin:applovin-sdk:11.5.
|
|
153
|
+
implementation 'com.applovin:applovin-sdk:11.5.3'
|
|
154
154
|
}
|
|
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|
|
3
3
|
distributionPath=wrapper/dists
|
|
4
4
|
zipStoreBase=GRADLE_USER_HOME
|
|
5
5
|
zipStorePath=wrapper/dists
|
|
6
|
-
distributionUrl=https\://services.gradle.org/distributions/gradle-6.
|
|
6
|
+
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-all.zip
|
|
@@ -495,13 +495,13 @@ public class AppLovinMAXModule
|
|
|
495
495
|
}
|
|
496
496
|
|
|
497
497
|
@ReactMethod()
|
|
498
|
-
public void setConsentFlowEnabled(final boolean enabled) {}
|
|
498
|
+
public void setConsentFlowEnabled(final boolean enabled) { }
|
|
499
499
|
|
|
500
500
|
@ReactMethod()
|
|
501
|
-
public void setPrivacyPolicyUrl(final String urlString) {}
|
|
501
|
+
public void setPrivacyPolicyUrl(final String urlString) { }
|
|
502
502
|
|
|
503
503
|
@ReactMethod()
|
|
504
|
-
public void setTermsOfServiceUrl(final String urlString) {}
|
|
504
|
+
public void setTermsOfServiceUrl(final String urlString) { }
|
|
505
505
|
|
|
506
506
|
// Data Passing
|
|
507
507
|
|
|
@@ -940,6 +940,10 @@ public class AppLovinMAXModule
|
|
|
940
940
|
{
|
|
941
941
|
name = "OnRewardedAdLoadedEvent";
|
|
942
942
|
}
|
|
943
|
+
else if ( MaxAdFormat.NATIVE == adFormat )
|
|
944
|
+
{
|
|
945
|
+
name = "OnNativeAdLoadedEvent";
|
|
946
|
+
}
|
|
943
947
|
else
|
|
944
948
|
{
|
|
945
949
|
logInvalidAdFormat( adFormat );
|
|
@@ -949,6 +953,11 @@ public class AppLovinMAXModule
|
|
|
949
953
|
sendReactNativeEvent( name, getAdInfo( ad ) );
|
|
950
954
|
}
|
|
951
955
|
|
|
956
|
+
public void handleNativeAdLoadFailureForAdUnitId(final String adUnitId, final MaxError error)
|
|
957
|
+
{
|
|
958
|
+
sendReactNativeEventForAdLoadFailed( "OnNativeAdLoadFailedEvent", adUnitId, error );
|
|
959
|
+
}
|
|
960
|
+
|
|
952
961
|
@Override
|
|
953
962
|
public void onAdLoadFailed(final String adUnitId, final MaxError error)
|
|
954
963
|
{
|
|
@@ -1021,6 +1030,10 @@ public class AppLovinMAXModule
|
|
|
1021
1030
|
{
|
|
1022
1031
|
name = "OnRewardedAdClickedEvent";
|
|
1023
1032
|
}
|
|
1033
|
+
else if ( MaxAdFormat.NATIVE == adFormat )
|
|
1034
|
+
{
|
|
1035
|
+
name = "OnNativeAdClickedEvent";
|
|
1036
|
+
}
|
|
1024
1037
|
else
|
|
1025
1038
|
{
|
|
1026
1039
|
logInvalidAdFormat( adFormat );
|
|
@@ -1141,6 +1154,10 @@ public class AppLovinMAXModule
|
|
|
1141
1154
|
{
|
|
1142
1155
|
name = "OnRewardedAdRevenuePaid";
|
|
1143
1156
|
}
|
|
1157
|
+
else if ( MaxAdFormat.NATIVE == adFormat )
|
|
1158
|
+
{
|
|
1159
|
+
name = "OnNativeAdRevenuePaid";
|
|
1160
|
+
}
|
|
1144
1161
|
else
|
|
1145
1162
|
{
|
|
1146
1163
|
logInvalidAdFormat( adFormat );
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
package com.applovin.reactnative;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.text.TextUtils;
|
|
5
|
+
import android.view.View;
|
|
6
|
+
import android.view.ViewGroup;
|
|
7
|
+
import android.widget.ImageView;
|
|
8
|
+
|
|
9
|
+
import com.applovin.mediation.MaxAd;
|
|
10
|
+
import com.applovin.mediation.MaxError;
|
|
11
|
+
import com.applovin.mediation.nativeAds.MaxNativeAd;
|
|
12
|
+
import com.applovin.mediation.nativeAds.MaxNativeAd.MaxNativeAdImage;
|
|
13
|
+
import com.applovin.mediation.nativeAds.MaxNativeAdListener;
|
|
14
|
+
import com.applovin.mediation.nativeAds.MaxNativeAdLoader;
|
|
15
|
+
import com.applovin.mediation.nativeAds.MaxNativeAdView;
|
|
16
|
+
import com.facebook.react.bridge.Arguments;
|
|
17
|
+
import com.facebook.react.bridge.ReactContext;
|
|
18
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
19
|
+
import com.facebook.react.bridge.WritableMap;
|
|
20
|
+
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
|
21
|
+
import com.facebook.react.views.view.ReactViewGroup;
|
|
22
|
+
|
|
23
|
+
import java.util.ArrayList;
|
|
24
|
+
import java.util.List;
|
|
25
|
+
import java.util.Map;
|
|
26
|
+
import java.util.concurrent.atomic.AtomicBoolean;
|
|
27
|
+
|
|
28
|
+
import androidx.annotation.Nullable;
|
|
29
|
+
|
|
30
|
+
import static com.applovin.sdk.AppLovinSdkUtils.runOnUiThreadDelayed;
|
|
31
|
+
|
|
32
|
+
public class AppLovinMAXNativeAdView
|
|
33
|
+
extends ReactViewGroup
|
|
34
|
+
{
|
|
35
|
+
private final ReactContext reactContext;
|
|
36
|
+
@Nullable
|
|
37
|
+
private MaxNativeAdLoader adLoader;
|
|
38
|
+
@Nullable
|
|
39
|
+
private MaxAd nativeAd;
|
|
40
|
+
private final AtomicBoolean isLoading = new AtomicBoolean(); // Guard against repeated ad loads
|
|
41
|
+
|
|
42
|
+
// JavaScript properties
|
|
43
|
+
private String adUnitId;
|
|
44
|
+
@Nullable
|
|
45
|
+
private String placement;
|
|
46
|
+
@Nullable
|
|
47
|
+
private String customData;
|
|
48
|
+
@Nullable
|
|
49
|
+
private Map<String, Object> extraParameters;
|
|
50
|
+
|
|
51
|
+
// TODO: Allow publisher to select which views are clickable and which isn't via prop
|
|
52
|
+
private final List<View> clickableViews = new ArrayList<>();
|
|
53
|
+
|
|
54
|
+
public AppLovinMAXNativeAdView(final Context context)
|
|
55
|
+
{
|
|
56
|
+
super( context );
|
|
57
|
+
reactContext = (ReactContext) context;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public void destroy()
|
|
61
|
+
{
|
|
62
|
+
maybeDestroyCurrentAd();
|
|
63
|
+
|
|
64
|
+
if ( adLoader != null )
|
|
65
|
+
{
|
|
66
|
+
adLoader.destroy();
|
|
67
|
+
adLoader = null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public void setAdUnitId(final String value)
|
|
72
|
+
{
|
|
73
|
+
if ( TextUtils.isEmpty( value ) ) return;
|
|
74
|
+
|
|
75
|
+
adUnitId = value;
|
|
76
|
+
|
|
77
|
+
// Explicitly invoke ad load now that Ad Unit ID is set, but do so after 0.25s to allow other props to set
|
|
78
|
+
postDelayed( this::loadAd, 250 );
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public void setPlacement(@Nullable final String value)
|
|
82
|
+
{
|
|
83
|
+
placement = value;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public void setCustomData(@Nullable final String value)
|
|
87
|
+
{
|
|
88
|
+
customData = value;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public void setExtraParameters(@Nullable final ReadableMap readableMap)
|
|
92
|
+
{
|
|
93
|
+
if ( readableMap != null )
|
|
94
|
+
{
|
|
95
|
+
extraParameters = readableMap.toHashMap();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
public void loadAd()
|
|
100
|
+
{
|
|
101
|
+
if ( isLoading.compareAndSet( false, true ) )
|
|
102
|
+
{
|
|
103
|
+
AppLovinMAXModule.d( "Loading a native ad for Ad Unit ID: " + adUnitId + "..." );
|
|
104
|
+
|
|
105
|
+
if ( adLoader == null || !adUnitId.equals( adLoader.getAdUnitId() ) )
|
|
106
|
+
{
|
|
107
|
+
adLoader = new MaxNativeAdLoader( adUnitId, AppLovinMAXModule.getInstance().getSdk(), reactContext );
|
|
108
|
+
adLoader.setRevenueListener( AppLovinMAXModule.getInstance() );
|
|
109
|
+
adLoader.setNativeAdListener( new NativeAdListener() );
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
adLoader.setPlacement( placement );
|
|
113
|
+
adLoader.setCustomData( customData );
|
|
114
|
+
|
|
115
|
+
if ( extraParameters != null )
|
|
116
|
+
{
|
|
117
|
+
for ( Map.Entry<String, Object> entry : extraParameters.entrySet() )
|
|
118
|
+
{
|
|
119
|
+
adLoader.setExtraParameter( entry.getKey(), (String) entry.getValue() );
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
adLoader.loadAd();
|
|
124
|
+
}
|
|
125
|
+
else
|
|
126
|
+
{
|
|
127
|
+
AppLovinMAXModule.e( "Ignoring request to load native ad for Ad Unit ID " + adUnitId + ", another ad load in progress" );
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/// Views to Replace
|
|
132
|
+
|
|
133
|
+
public void setTitleView(final int tag)
|
|
134
|
+
{
|
|
135
|
+
if ( nativeAd.getNativeAd().getTitle() == null ) return;
|
|
136
|
+
|
|
137
|
+
View view = findViewById( tag );
|
|
138
|
+
view.setClickable( true );
|
|
139
|
+
|
|
140
|
+
clickableViews.add( view );
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
public void setAdvertiserView(final int tag)
|
|
144
|
+
{
|
|
145
|
+
if ( nativeAd.getNativeAd().getAdvertiser() == null ) return;
|
|
146
|
+
|
|
147
|
+
View view = findViewById( tag );
|
|
148
|
+
view.setClickable( true );
|
|
149
|
+
|
|
150
|
+
clickableViews.add( view );
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
public void setBodyView(final int tag)
|
|
154
|
+
{
|
|
155
|
+
if ( nativeAd.getNativeAd().getBody() == null ) return;
|
|
156
|
+
|
|
157
|
+
View view = findViewById( tag );
|
|
158
|
+
view.setClickable( true );
|
|
159
|
+
|
|
160
|
+
clickableViews.add( view );
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
public void setCallToActionView(final int tag)
|
|
164
|
+
{
|
|
165
|
+
if ( nativeAd.getNativeAd().getCallToAction() == null ) return;
|
|
166
|
+
|
|
167
|
+
View view = findViewById( tag );
|
|
168
|
+
view.setClickable( true );
|
|
169
|
+
|
|
170
|
+
clickableViews.add( view );
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public void setMediaView(final int tag)
|
|
174
|
+
{
|
|
175
|
+
View mediaView = nativeAd.getNativeAd().getMediaView();
|
|
176
|
+
if ( mediaView == null ) return;
|
|
177
|
+
|
|
178
|
+
ViewGroup view = findViewById( tag );
|
|
179
|
+
if ( view == null )
|
|
180
|
+
{
|
|
181
|
+
AppLovinMAXModule.e( "Cannot find a media view with tag \"" + tag + "\" for " + adUnitId );
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
clickableViews.add( view );
|
|
186
|
+
|
|
187
|
+
mediaView.measure( MeasureSpec.makeMeasureSpec( view.getWidth(), MeasureSpec.EXACTLY ),
|
|
188
|
+
MeasureSpec.makeMeasureSpec( view.getHeight(), MeasureSpec.EXACTLY ) );
|
|
189
|
+
mediaView.layout( 0, 0, view.getWidth(), view.getHeight() );
|
|
190
|
+
view.addView( mediaView );
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
public void setOptionsView(final int tag)
|
|
194
|
+
{
|
|
195
|
+
View optionsView = nativeAd.getNativeAd().getOptionsView();
|
|
196
|
+
if ( optionsView == null ) return;
|
|
197
|
+
|
|
198
|
+
ViewGroup view = findViewById( tag );
|
|
199
|
+
if ( view == null )
|
|
200
|
+
{
|
|
201
|
+
AppLovinMAXModule.e( "Cannot find an options view with tag \"" + tag + "\" for " + adUnitId );
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
optionsView.measure( MeasureSpec.makeMeasureSpec( view.getWidth(), MeasureSpec.EXACTLY ),
|
|
206
|
+
MeasureSpec.makeMeasureSpec( view.getHeight(), MeasureSpec.EXACTLY ) );
|
|
207
|
+
optionsView.layout( 0, 0, view.getWidth(), view.getHeight() );
|
|
208
|
+
view.addView( optionsView );
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
public void setIconView(final int tag)
|
|
212
|
+
{
|
|
213
|
+
ImageView view = findViewById( tag );
|
|
214
|
+
if ( view == null )
|
|
215
|
+
{
|
|
216
|
+
AppLovinMAXModule.e( "Cannot find an icon image with tag \"" + tag + "\" for " + adUnitId );
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
view.setClickable( true );
|
|
221
|
+
clickableViews.add( view );
|
|
222
|
+
|
|
223
|
+
MaxNativeAdImage icon = nativeAd.getNativeAd().getIcon();
|
|
224
|
+
|
|
225
|
+
// Check if "URL" was missing and therefore need to set the image data
|
|
226
|
+
if ( icon.getUri() == null && icon.getDrawable() != null )
|
|
227
|
+
{
|
|
228
|
+
view.setImageDrawable( nativeAd.getNativeAd().getIcon().getDrawable() );
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/// Ad Loader Callback
|
|
233
|
+
|
|
234
|
+
class NativeAdListener
|
|
235
|
+
extends MaxNativeAdListener
|
|
236
|
+
{
|
|
237
|
+
@Override
|
|
238
|
+
public void onNativeAdLoaded(@Nullable final MaxNativeAdView nativeAdView, final MaxAd ad)
|
|
239
|
+
{
|
|
240
|
+
AppLovinMAXModule.d( "Native ad loaded: " + ad );
|
|
241
|
+
|
|
242
|
+
// Log a warning if it is a template native ad returned - as our plugin will be responsible for re-rendering the native ad's assets
|
|
243
|
+
if ( nativeAdView != null )
|
|
244
|
+
{
|
|
245
|
+
isLoading.set( false );
|
|
246
|
+
|
|
247
|
+
AppLovinMAXModule.e( "Native ad is of template type, failing ad load..." );
|
|
248
|
+
AppLovinMAXModule.getInstance().handleNativeAdLoadFailureForAdUnitId( adUnitId, null );
|
|
249
|
+
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
maybeDestroyCurrentAd();
|
|
254
|
+
|
|
255
|
+
nativeAd = ad;
|
|
256
|
+
|
|
257
|
+
// Notify `AppLovinNativeAdView.js`
|
|
258
|
+
sendAdLoadedReactNativeEventForAd( ad.getNativeAd() );
|
|
259
|
+
|
|
260
|
+
// After notifying the RN layer - have slight delay to let views bind to this layer in `clickableViews` before registering
|
|
261
|
+
runOnUiThreadDelayed( () -> {
|
|
262
|
+
// Notify publisher
|
|
263
|
+
AppLovinMAXModule.getInstance().onAdLoaded( ad );
|
|
264
|
+
|
|
265
|
+
adLoader.a( clickableViews, AppLovinMAXNativeAdView.this, ad );
|
|
266
|
+
adLoader.b( ad );
|
|
267
|
+
|
|
268
|
+
isLoading.set( false );
|
|
269
|
+
}, 500L );
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
@Override
|
|
273
|
+
public void onNativeAdLoadFailed(final String adUnitId, final MaxError error)
|
|
274
|
+
{
|
|
275
|
+
isLoading.set( false );
|
|
276
|
+
|
|
277
|
+
AppLovinMAXModule.e( "Failed to load native ad for Ad Unit ID " + adUnitId + " with error: " + error );
|
|
278
|
+
|
|
279
|
+
// Notify publisher
|
|
280
|
+
AppLovinMAXModule.getInstance().handleNativeAdLoadFailureForAdUnitId( adUnitId, error );
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
@Override
|
|
284
|
+
public void onNativeAdClicked(final MaxAd ad)
|
|
285
|
+
{
|
|
286
|
+
AppLovinMAXModule.getInstance().onAdClicked( ad );
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
private void sendAdLoadedReactNativeEventForAd(final MaxNativeAd ad)
|
|
291
|
+
{
|
|
292
|
+
WritableMap jsNativeAd = Arguments.createMap();
|
|
293
|
+
|
|
294
|
+
jsNativeAd.putString( "title", ad.getTitle() );
|
|
295
|
+
if ( ad.getAdvertiser() != null )
|
|
296
|
+
{
|
|
297
|
+
jsNativeAd.putString( "advertiser", ad.getAdvertiser() );
|
|
298
|
+
}
|
|
299
|
+
if ( ad.getBody() != null )
|
|
300
|
+
{
|
|
301
|
+
jsNativeAd.putString( "body", ad.getBody() );
|
|
302
|
+
}
|
|
303
|
+
if ( ad.getCallToAction() != null )
|
|
304
|
+
{
|
|
305
|
+
jsNativeAd.putString( "callToAction", ad.getCallToAction() );
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
MaxNativeAdImage icon = ad.getIcon();
|
|
309
|
+
if ( icon != null )
|
|
310
|
+
{
|
|
311
|
+
if ( icon.getUri() != null )
|
|
312
|
+
{
|
|
313
|
+
jsNativeAd.putString( "url", icon.getUri().toString() );
|
|
314
|
+
}
|
|
315
|
+
else if ( icon.getDrawable() != null )
|
|
316
|
+
{
|
|
317
|
+
jsNativeAd.putBoolean( "image", true );
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
float aspectRatio = ad.getMediaContentAspectRatio();
|
|
322
|
+
if ( !Float.isNaN( aspectRatio ) )
|
|
323
|
+
{
|
|
324
|
+
jsNativeAd.putDouble( "mediaContentAspectRatio", aspectRatio );
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Send to `AppLovinNativeAdView.js` to render the views
|
|
328
|
+
reactContext.getJSModule( RCTEventEmitter.class ).receiveEvent( getId(), "onAdLoaded", jsNativeAd );
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
private void maybeDestroyCurrentAd()
|
|
332
|
+
{
|
|
333
|
+
if ( nativeAd != null )
|
|
334
|
+
{
|
|
335
|
+
if ( nativeAd.getNativeAd() != null )
|
|
336
|
+
{
|
|
337
|
+
View view = nativeAd.getNativeAd().getMediaView();
|
|
338
|
+
if ( view != null )
|
|
339
|
+
{
|
|
340
|
+
ViewGroup parentView = (ViewGroup) view.getParent();
|
|
341
|
+
if ( parentView != null )
|
|
342
|
+
{
|
|
343
|
+
parentView.removeView( view );
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
view = nativeAd.getNativeAd().getOptionsView();
|
|
348
|
+
if ( view != null )
|
|
349
|
+
{
|
|
350
|
+
ViewGroup parentView = (ViewGroup) view.getParent();
|
|
351
|
+
if ( parentView != null )
|
|
352
|
+
{
|
|
353
|
+
parentView.removeView( view );
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
adLoader.destroy( nativeAd );
|
|
359
|
+
|
|
360
|
+
nativeAd = null;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
clickableViews.clear();
|
|
364
|
+
}
|
|
365
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
package com.applovin.reactnative;
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
4
|
+
import com.facebook.react.bridge.ReadableArray;
|
|
5
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
6
|
+
import com.facebook.react.common.MapBuilder;
|
|
7
|
+
import com.facebook.react.uimanager.ThemedReactContext;
|
|
8
|
+
import com.facebook.react.uimanager.ViewGroupManager;
|
|
9
|
+
import com.facebook.react.uimanager.annotations.ReactProp;
|
|
10
|
+
|
|
11
|
+
import java.util.Map;
|
|
12
|
+
|
|
13
|
+
import androidx.annotation.NonNull;
|
|
14
|
+
import androidx.annotation.Nullable;
|
|
15
|
+
|
|
16
|
+
public class AppLovinMAXNativeAdViewManager
|
|
17
|
+
extends ViewGroupManager<AppLovinMAXNativeAdView>
|
|
18
|
+
{
|
|
19
|
+
public static final String REACT_CLASS = "AppLovinMAXNativeAdView";
|
|
20
|
+
|
|
21
|
+
public final int COMMAND_LOAD_AD = 1;
|
|
22
|
+
|
|
23
|
+
public AppLovinMAXNativeAdViewManager(final ReactApplicationContext callerContext) { }
|
|
24
|
+
|
|
25
|
+
@NonNull
|
|
26
|
+
@Override
|
|
27
|
+
protected AppLovinMAXNativeAdView createViewInstance(@NonNull final ThemedReactContext reactContext)
|
|
28
|
+
{
|
|
29
|
+
return new AppLovinMAXNativeAdView( reactContext );
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@NonNull
|
|
33
|
+
@Override
|
|
34
|
+
public String getName()
|
|
35
|
+
{
|
|
36
|
+
return REACT_CLASS;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/// Callback to JavaScript
|
|
40
|
+
|
|
41
|
+
@Nullable
|
|
42
|
+
@Override
|
|
43
|
+
public Map<String, Object> getExportedCustomDirectEventTypeConstants()
|
|
44
|
+
{
|
|
45
|
+
return MapBuilder.<String, Object>builder()
|
|
46
|
+
.put( "onAdLoaded", MapBuilder.of( "registrationName", "onAdLoaded" ) )
|
|
47
|
+
.build();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/// Call from JavaScript
|
|
51
|
+
|
|
52
|
+
@Nullable
|
|
53
|
+
@Override
|
|
54
|
+
public Map<String, Integer> getCommandsMap()
|
|
55
|
+
{
|
|
56
|
+
return MapBuilder.of(
|
|
57
|
+
"loadAd", COMMAND_LOAD_AD
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// NOTE: the method is deprecated but the new version won't work
|
|
62
|
+
@Override
|
|
63
|
+
public void receiveCommand(@NonNull final AppLovinMAXNativeAdView root, final int commandId, @Nullable final ReadableArray args)
|
|
64
|
+
{
|
|
65
|
+
switch ( commandId )
|
|
66
|
+
{
|
|
67
|
+
case COMMAND_LOAD_AD:
|
|
68
|
+
root.loadAd();
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/// Property Setters
|
|
74
|
+
|
|
75
|
+
@ReactProp(name = "adUnitId")
|
|
76
|
+
public void setAdUnitId(final AppLovinMAXNativeAdView view, final String value)
|
|
77
|
+
{
|
|
78
|
+
view.setAdUnitId( value );
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@ReactProp(name = "placement")
|
|
82
|
+
public void setPlacement(final AppLovinMAXNativeAdView view, @Nullable final String value)
|
|
83
|
+
{
|
|
84
|
+
view.setPlacement( value );
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@ReactProp(name = "customData")
|
|
88
|
+
public void setCustomData(final AppLovinMAXNativeAdView view, @Nullable final String value)
|
|
89
|
+
{
|
|
90
|
+
view.setCustomData( value );
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@ReactProp(name = "extraParameters")
|
|
94
|
+
public void setExtraParameters(final AppLovinMAXNativeAdView view, @Nullable final ReadableMap value)
|
|
95
|
+
{
|
|
96
|
+
view.setExtraParameters( value );
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@ReactProp(name = "titleView")
|
|
100
|
+
public void setTitleView(final AppLovinMAXNativeAdView view, final int value)
|
|
101
|
+
{
|
|
102
|
+
view.setTitleView( value );
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@ReactProp(name = "advertiserView")
|
|
106
|
+
public void setAdvertiserView(final AppLovinMAXNativeAdView view, final int value)
|
|
107
|
+
{
|
|
108
|
+
view.setAdvertiserView( value );
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
@ReactProp(name = "bodyView")
|
|
112
|
+
public void setBodyView(final AppLovinMAXNativeAdView view, final int value)
|
|
113
|
+
{
|
|
114
|
+
view.setBodyView( value );
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@ReactProp(name = "callToActionView")
|
|
118
|
+
public void setCallToActionView(final AppLovinMAXNativeAdView view, final int value)
|
|
119
|
+
{
|
|
120
|
+
view.setCallToActionView( value );
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@ReactProp(name = "mediaView")
|
|
124
|
+
public void setMediaView(final AppLovinMAXNativeAdView view, final int value)
|
|
125
|
+
{
|
|
126
|
+
view.setMediaView( value );
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@ReactProp(name = "optionsView")
|
|
130
|
+
public void setOptionsView(final AppLovinMAXNativeAdView view, final int value)
|
|
131
|
+
{
|
|
132
|
+
view.setOptionsView( value );
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@ReactProp(name = "iconView")
|
|
136
|
+
public void setIconView(final AppLovinMAXNativeAdView view, final int value)
|
|
137
|
+
{
|
|
138
|
+
view.setIconView( value );
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@Override
|
|
142
|
+
public void onDropViewInstance(@NonNull final AppLovinMAXNativeAdView view)
|
|
143
|
+
{
|
|
144
|
+
view.destroy();
|
|
145
|
+
|
|
146
|
+
super.onDropViewInstance( view );
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -27,8 +27,9 @@ public class AppLovinMAXPackage
|
|
|
27
27
|
@Override
|
|
28
28
|
public @NonNull List<ViewManager> createViewManagers(@NonNull final ReactApplicationContext reactContext)
|
|
29
29
|
{
|
|
30
|
-
List<ViewManager> viewManagers = new ArrayList<>(
|
|
30
|
+
List<ViewManager> viewManagers = new ArrayList<>( 2 );
|
|
31
31
|
viewManagers.add( new AppLovinMAXAdViewManager( reactContext ) );
|
|
32
|
+
viewManagers.add( new AppLovinMAXNativeAdViewManager( reactContext ) );
|
|
32
33
|
return viewManagers;
|
|
33
34
|
}
|
|
34
35
|
}
|
package/ios/AppLovinMAX.h
CHANGED
|
@@ -36,6 +36,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
36
36
|
*/
|
|
37
37
|
- (void)log:(NSString *)format, ...;
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Convenience method for invoking a native ad load failure event.
|
|
41
|
+
*/
|
|
42
|
+
- (void)handleNativeAdLoadFailureForAdUnitIdentifier:(NSString *)adUnitIdentifier error:(nullable MAError *)error;
|
|
43
|
+
|
|
39
44
|
@end
|
|
40
45
|
|
|
41
46
|
NS_ASSUME_NONNULL_END
|
package/ios/AppLovinMAX.m
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
//
|
|
8
8
|
|
|
9
9
|
#import "AppLovinMAX.h"
|
|
10
|
+
#import "AppLovinMAXNativeAdView.h"
|
|
10
11
|
|
|
11
12
|
#define ROOT_VIEW_CONTROLLER (UIApplication.sharedApplication.keyWindow.rootViewController)
|
|
12
13
|
|
|
@@ -207,8 +208,8 @@ RCT_EXPORT_METHOD(initialize:(NSString *)pluginVersion :(NSString *)sdkKey :(RCT
|
|
|
207
208
|
|
|
208
209
|
[self setPendingExtraParametersIfNeeded: self.sdk.settings];
|
|
209
210
|
|
|
210
|
-
[self.sdk initializeSdkWithCompletionHandler:^(ALSdkConfiguration *configuration)
|
|
211
|
-
|
|
211
|
+
[self.sdk initializeSdkWithCompletionHandler:^(ALSdkConfiguration *configuration) {
|
|
212
|
+
|
|
212
213
|
[self log: @"SDK initialized"];
|
|
213
214
|
|
|
214
215
|
self.sdkConfiguration = configuration;
|
|
@@ -731,6 +732,10 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
|
|
|
731
732
|
{
|
|
732
733
|
name = @"OnRewardedAdLoadedEvent";
|
|
733
734
|
}
|
|
735
|
+
else if ( MAAdFormat.native == adFormat )
|
|
736
|
+
{
|
|
737
|
+
name = @"OnNativeAdLoadedEvent";
|
|
738
|
+
}
|
|
734
739
|
else
|
|
735
740
|
{
|
|
736
741
|
[self logInvalidAdFormat: adFormat];
|
|
@@ -740,6 +745,16 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
|
|
|
740
745
|
[self sendReactNativeEventWithName: name body: [self adInfoForAd: ad]];
|
|
741
746
|
}
|
|
742
747
|
|
|
748
|
+
- (void)handleNativeAdLoadFailureForAdUnitIdentifier:(NSString *)adUnitIdentifier error:(nullable MAError *)error
|
|
749
|
+
{
|
|
750
|
+
[self sendReactNativeEventWithName: @"OnNativeAdLoadFailedEvent"
|
|
751
|
+
body: @{@"adUnitId" : adUnitIdentifier,
|
|
752
|
+
@"code" : @(error.code),
|
|
753
|
+
@"message" : error.message,
|
|
754
|
+
@"adLoadFailureInfo" : error.adLoadFailureInfo ?: @"",
|
|
755
|
+
@"waterfall": [self createAdWaterfallInfo: error.waterfall]}];
|
|
756
|
+
}
|
|
757
|
+
|
|
743
758
|
- (void)didFailToLoadAdForAdUnitIdentifier:(NSString *)adUnitIdentifier withError:(MAError *)error
|
|
744
759
|
{
|
|
745
760
|
if ( !adUnitIdentifier )
|
|
@@ -794,6 +809,10 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
|
|
|
794
809
|
{
|
|
795
810
|
name = @"OnRewardedAdClickedEvent";
|
|
796
811
|
}
|
|
812
|
+
else if ( MAAdFormat.native == adFormat )
|
|
813
|
+
{
|
|
814
|
+
name = @"OnNativeAdClickedEvent";
|
|
815
|
+
}
|
|
797
816
|
else
|
|
798
817
|
{
|
|
799
818
|
[self logInvalidAdFormat: adFormat];
|
|
@@ -910,6 +929,10 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
|
|
|
910
929
|
{
|
|
911
930
|
name = @"OnRewardedAdRevenuePaid";
|
|
912
931
|
}
|
|
932
|
+
else if ( MAAdFormat.native == adFormat )
|
|
933
|
+
{
|
|
934
|
+
name = @"OnNativeAdRevenuePaid";
|
|
935
|
+
}
|
|
913
936
|
else
|
|
914
937
|
{
|
|
915
938
|
[self logInvalidAdFormat: adFormat];
|
|
@@ -1574,7 +1597,12 @@ RCT_EXPORT_METHOD(setRewardedAdExtraParameter:(NSString *)adUnitIdentifier :(NSS
|
|
|
1574
1597
|
@"OnRewardedAdFailedToDisplayEvent",
|
|
1575
1598
|
@"OnRewardedAdHiddenEvent",
|
|
1576
1599
|
@"OnRewardedAdReceivedRewardEvent",
|
|
1577
|
-
@"OnRewardedAdRevenuePaid"
|
|
1600
|
+
@"OnRewardedAdRevenuePaid",
|
|
1601
|
+
|
|
1602
|
+
@"OnNativeAdLoadedEvent",
|
|
1603
|
+
@"OnNativeAdLoadFailedEvent",
|
|
1604
|
+
@"OnNativeAdClickedEvent",
|
|
1605
|
+
@"OnNativeAdRevenuePaid"];
|
|
1578
1606
|
}
|
|
1579
1607
|
|
|
1580
1608
|
- (void)startObserving
|