react-native-applovin-max 2.1.3 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,6 +9,7 @@
9
9
  #import "AppLovinMAXAdViewManager.h"
10
10
  #import <AppLovinSDK/AppLovinSDK.h>
11
11
  #import "AppLovinMAX.h"
12
+ #import <React/RCTUIManager.h>
12
13
 
13
14
  // Internal
14
15
  @interface NSString (ALUtils)
@@ -17,50 +18,89 @@
17
18
 
18
19
  @interface AppLovinMAXAdViewManager()
19
20
 
20
- // View properties
21
- @property (nonatomic, strong) UIView *containerView;
22
- @property (nonatomic, strong) MAAdView *adView;
23
-
24
- // Properties that need to be set before creating MAAdView
25
- @property (nonatomic, copy) NSString *adUnitIdentifier;
26
- @property (nonatomic, weak) MAAdFormat *adFormat;
21
+ // Dictionaries from id of the React view to the corresponding ad unit id and ad format.
22
+ // Both must be set before the MAAdView is created.
23
+ @property (nonatomic, strong) NSMutableDictionary<NSNumber *, NSString *> *adUnitIdRegistry;
24
+ @property (nonatomic, strong) NSMutableDictionary<NSNumber *, MAAdFormat *> *adFormatRegistry;
27
25
 
28
26
  @end
29
27
 
30
28
  @implementation AppLovinMAXAdViewManager
31
29
  RCT_EXPORT_MODULE(AppLovinMAXAdView)
32
30
 
31
+ // Overridding `init` requires main queue
32
+ + (BOOL)requiresMainQueueSetup
33
+ {
34
+ return YES;
35
+ }
36
+
37
+ - (instancetype)init
38
+ {
39
+ self = [super init];
40
+ if ( self )
41
+ {
42
+ self.adUnitIdRegistry = [NSMutableDictionary dictionary];
43
+ self.adFormatRegistry = [NSMutableDictionary dictionary];
44
+ }
45
+ return self;
46
+ }
47
+
33
48
  - (UIView *)view
34
49
  {
35
50
  // NOTE: Do not set frame or backgroundColor as RN will overwrite the values set by your custom class in order to match your JavaScript component's layout props - hence wrapper
36
- self.containerView = [[UIView alloc] init];
37
-
38
- return self.containerView;
51
+ return [[UIView alloc] init];
39
52
  }
40
53
 
41
- RCT_CUSTOM_VIEW_PROPERTY(adUnitId, NSString, MAAdView)
54
+ // NOTE: `nonnull` must be annotated here for this RN export to work at runtime
55
+ RCT_EXPORT_METHOD(setAdUnitId:(nonnull NSNumber *)viewTag toAdUnitId:(NSString *)adUnitId)
42
56
  {
43
- self.adUnitIdentifier = [RCTConvert NSString: json];
44
- [self attachAdViewIfNeededForAdUnitIdentifier: self.adUnitIdentifier adFormat: self.adFormat];
57
+ [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
58
+
59
+ // NOTE: iOS caches the native view via `viewTag` when you remove it from screen (unlike Android)
60
+ UIView *view = viewRegistry[viewTag];
61
+ if ( !view )
62
+ {
63
+ RCTLogError(@"Cannot find UIView with tag %@", viewTag);
64
+ return;
65
+ }
66
+
67
+ self.adUnitIdRegistry[viewTag] = adUnitId;
68
+
69
+ [self attachAdViewIfNeededForAdUnitIdentifier: self.adUnitIdRegistry[viewTag]
70
+ adFormat: self.adFormatRegistry[viewTag]
71
+ containerView: view];
72
+ }];
45
73
  }
46
74
 
47
- RCT_CUSTOM_VIEW_PROPERTY(adFormat, NSString, MAAdView)
75
+ // NOTE: `nonnull` must be annotated here for this RN export to work at runtime
76
+ RCT_EXPORT_METHOD(setAdFormat:(nonnull NSNumber *)viewTag toAdFormat:(NSString *)adFormatString)
48
77
  {
49
- NSString *adFormatStr = [RCTConvert NSString: json];
50
-
51
- if ( [@"banner" isEqualToString: adFormatStr] )
52
- {
53
- self.adFormat = DEVICE_SPECIFIC_ADVIEW_AD_FORMAT;
54
- }
55
- else if ( [@"mrec" isEqualToString: adFormatStr] )
56
- {
57
- self.adFormat = MAAdFormat.mrec;
58
- }
59
-
60
- [self attachAdViewIfNeededForAdUnitIdentifier: self.adUnitIdentifier adFormat: self.adFormat];
78
+ [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
79
+
80
+ // NOTE: iOS caches the native view via `viewTag` when you remove it from screen (unlike Android)
81
+ UIView *view = viewRegistry[viewTag];
82
+ if ( !view )
83
+ {
84
+ RCTLogError(@"Cannot find UIView with tag %@", viewTag);
85
+ return;
86
+ }
87
+
88
+ if ( [@"banner" isEqualToString: adFormatString] )
89
+ {
90
+ self.adFormatRegistry[viewTag] = DEVICE_SPECIFIC_ADVIEW_AD_FORMAT;
91
+ }
92
+ else if ( [@"mrec" isEqualToString: adFormatString] )
93
+ {
94
+ self.adFormatRegistry[viewTag] = MAAdFormat.mrec;
95
+ }
96
+
97
+ [self attachAdViewIfNeededForAdUnitIdentifier: self.adUnitIdRegistry[viewTag]
98
+ adFormat: self.adFormatRegistry[viewTag]
99
+ containerView: view];
100
+ }];
61
101
  }
62
102
 
63
- - (void)attachAdViewIfNeededForAdUnitIdentifier:(NSString *)adUnitIdentifier adFormat:(MAAdFormat *)adFormat
103
+ - (void)attachAdViewIfNeededForAdUnitIdentifier:(NSString *)adUnitIdentifier adFormat:(MAAdFormat *)adFormat containerView:(UIView *)containerView
64
104
  {
65
105
  // Run after delay to ensure SDK is attached to main module first
66
106
  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
@@ -68,31 +108,39 @@ RCT_CUSTOM_VIEW_PROPERTY(adFormat, NSString, MAAdView)
68
108
  // If ad unit id and format has been set - create and attach AdView
69
109
  if ( [adUnitIdentifier al_isValidString] && adFormat )
70
110
  {
111
+ MAAdView *adView = [self getMAAdViewFromContainerView: containerView];
71
112
  // Check if there's a previously-attached AdView
72
- if ( self.adView )
113
+ if ( adView )
73
114
  {
74
- [self.adView removeFromSuperview];
75
- [self.adView stopAutoRefresh];
115
+ [adView removeFromSuperview];
116
+ [adView stopAutoRefresh];
76
117
 
77
- self.adView = nil;
118
+ adView = nil;
78
119
  }
79
120
 
80
- self.adView = [AppLovinMAX.shared retrieveAdViewForAdUnitIdentifier: adUnitIdentifier
81
- adFormat: adFormat
82
- atPosition: @""
83
- withOffset: CGPointZero
84
- attach: NO];
85
- [self.adView loadAd];
121
+ adView = [AppLovinMAX.shared retrieveAdViewForAdUnitIdentifier: adUnitIdentifier
122
+ adFormat: adFormat
123
+ atPosition: @""
124
+ withOffset: CGPointZero
125
+ attach: NO];
126
+ [adView loadAd];
86
127
 
87
- [self.containerView addSubview: self.adView];
128
+ [containerView addSubview: adView];
88
129
 
89
- CGSize adViewSize = [AppLovinMAX adViewSizeForAdFormat: adFormat];
90
- [NSLayoutConstraint activateConstraints: @[[self.adView.widthAnchor constraintEqualToConstant: adViewSize.width],
91
- [self.adView.heightAnchor constraintEqualToConstant: adViewSize.height],
92
- [self.adView.centerXAnchor constraintEqualToAnchor: self.containerView.centerXAnchor],
93
- [self.adView.centerYAnchor constraintEqualToAnchor: self.containerView.centerYAnchor]]];
130
+ CGSize adViewSize = [adFormat adaptiveSizeForWidth: CGRectGetWidth(containerView.frame)];
131
+ [NSLayoutConstraint activateConstraints: @[[adView.widthAnchor constraintEqualToConstant: adViewSize.width],
132
+ [adView.heightAnchor constraintEqualToConstant: adViewSize.height],
133
+ [adView.centerXAnchor constraintEqualToAnchor: containerView.centerXAnchor],
134
+ [adView.centerYAnchor constraintEqualToAnchor: containerView.centerYAnchor]]];
94
135
  }
95
136
  });
96
137
  }
97
138
 
139
+ // MARK: - Helper Functions
140
+
141
+ - (nullable MAAdView *)getMAAdViewFromContainerView:(UIView *)view
142
+ {
143
+ return view.subviews.count > 0 ? ((MAAdView *) view.subviews.lastObject) : nil;
144
+ }
145
+
98
146
  @end
package/ios/Podfile CHANGED
@@ -35,5 +35,5 @@ 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'
38
+ pod 'AppLovinSDK', '10.3.6'
39
39
  end
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.1.3",
4
+ "version": "2.3.2",
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-Nativfe.git", :tag => "release_2_1_3" }
14
+ s.source = { :git => "https://github.com/AppLovin/AppLovin-MAX-React-Native.git", :tag => "release_2_3_2" }
15
15
 
16
16
  s.source_files = "ios/AppLovinMAX*.{h,m}"
17
17
 
18
18
  s.dependency "React"
19
- s.dependency "AppLovinSDK"
19
+ s.dependency "AppLovinSDK", "10.3.6"
20
20
  end
@@ -1,23 +1,111 @@
1
- import { requireNativeComponent } from "react-native";
1
+ import { requireNativeComponent, UIManager, findNodeHandle } from "react-native";
2
2
  import PropTypes from "prop-types";
3
3
  import React from "react";
4
4
  import AppLovinMAX from "./index.js";
5
5
 
6
6
  class AdView extends React.Component {
7
+
8
+ static defaultProps = {
9
+ adaptiveBannerEnabled: true
10
+ }
11
+
12
+ componentDidMount() {
13
+ this.setAdUnitId(this.props.adUnitId);
14
+ this.setAdFormat(this.props.adFormat);
15
+ this.setPlacement(this.props.placement);
16
+ this.setAdaptiveBannerEnabled(this.props.adaptiveBannerEnabled);
17
+ }
18
+
19
+ componentDidUpdate(prevProps) {
20
+ // Only call setters for actual changes.
21
+ if (prevProps.adUnitId !== this.props.adUnitId) {
22
+ this.setAdUnitId(this.props.adUnitId);
23
+ }
24
+
25
+ if (prevProps.adFormat !== this.props.adFormat) {
26
+ this.setAdFormat(this.props.adFormat);
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
+ }
36
+ }
37
+
7
38
  render() {
8
39
  let { style, ...otherProps } = this.props;
40
+
9
41
  return <AppLovinMAXAdView
10
- // This merges the pub-specified style with ours, but overwrites width/height.
11
- style={Object.assign({}, style, this.sizeForAdFormat(otherProps.adFormat))}
12
- {...otherProps} />;
42
+ // This merges the pub-specified style with ours, but overwrites width/height.
43
+ style = { Object.assign({}, style, this.sizeForAdFormat(otherProps.adFormat)) } {...otherProps }
44
+ />;
13
45
  }
14
-
46
+
47
+ // Helper Functions
48
+
15
49
  sizeForAdFormat(adFormat) {
16
- if (adFormat == AppLovinMAX.AdFormat.BANNER) {
17
- 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);
18
57
  } else {
19
- return {width: 300, height: 250}
58
+ height = AppLovinMAX.isTablet() ? 90 : 50;
20
59
  }
60
+
61
+ return { width: width, height: height }
62
+ } else {
63
+ return { width: 300, height: 250 }
64
+ }
65
+ }
66
+
67
+ setAdUnitId(adUnitId) {
68
+ UIManager.dispatchViewManagerCommand(
69
+ findNodeHandle(this),
70
+ Platform.OS === 'android' ? "setAdUnitId" : UIManager.getViewManagerConfig("AppLovinMAXAdView").Commands.setAdUnitId,
71
+ [adUnitId]
72
+ );
73
+ }
74
+
75
+ setAdFormat(adFormatStr) {
76
+ UIManager.dispatchViewManagerCommand(
77
+ findNodeHandle(this),
78
+ Platform.OS === 'android' ? "setAdFormat" : UIManager.getViewManagerConfig("AppLovinMAXAdView").Commands.setAdFormat,
79
+ [adFormatStr]
80
+ );
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
+ if (adFormat === AppLovinMAX.AdFormat.BANNER) {
91
+ AppLovinMAX.setBannerPlacement(adUnitId, placement);
92
+ } else if (adFormat === AppLovinMAX.AdFormat.MREC) {
93
+ AppLovinMAX.setMRecPlacement(adUnitId, 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
+ AppLovinMAX.setBannerExtraParameter(adUnitId, "adaptive_banner", enabled ? "true" : "false");
107
+ }
108
+ }
21
109
  }
22
110
  }
23
111
 
@@ -31,6 +119,16 @@ AdView.propTypes = {
31
119
  * A string value representing the ad format to load ads for. Should be either `AppLovinMAX.AdFormat.BANNER` or `AppLovinMAX.AdFormat.MREC`.
32
120
  */
33
121
  adFormat: PropTypes.string.isRequired,
122
+
123
+ /**
124
+ * A string value representing the placement name that you assign when you integrate each ad format, for granular reporting in ad events.
125
+ */
126
+ placement: PropTypes.string,
127
+
128
+ /**
129
+ * A boolean value representing whether or not to enable adaptive banners. Note that adaptive banners are enabled by default as of v2.3.0.
130
+ */
131
+ adaptiveBannerEnabled: PropTypes.bool,
34
132
  };
35
133
 
36
134
  // 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.1.3";
6
+ const VERSION = "2.3.2";
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,58 +0,0 @@
1
- ## Versions
2
-
3
- ## 2.1.3
4
- * Add support for latest SDKs v10.3.1 with new callbacks.
5
- ## 2.1.2
6
- * Fix banners and MRECs native UI components not clicking if not styled by parent dom.
7
- ## 2.1.1
8
- * Fix iOS projects not building.
9
- ## 2.1.0
10
- * Add API for passing in `errorInfo` for ad load failure callbacks with parameters "code", "message", and "adLoadFailureInfo".
11
- * Add API for passing in `errorInfo` for ad display failure callbacks with parameters "code" and "message".
12
- * 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);`.
13
- ## 2.0.6
14
- * Add support for latest SDKs v10.3.0 with new callbacks.
15
- ## 2.0.5
16
- * Fallback to SDK key in Android Manifest and Info.plist if not passed programmatically.
17
- * Add support for setting banner width.
18
- ## 2.0.4
19
- * Pass `"countryCode"` in initialization callback.
20
- ## 2.0.3
21
- * Fix ad callbacks not returning.
22
- ## 2.0.2
23
- * Remove `getAdInfo(adUnitId)` API in lieu of ad callbacks.
24
- * Return more data in ad callbacks in addition to `ad.adUnitId` (e.g. `adInfo.creativeId`, `adInfo.networkName`, `adInfo.placement`, `adInfo.revenue`).
25
- ## 2.0.1
26
- * Ensure exported iOS methods are invoked on the main queue.
27
- ## 2.0.0
28
- * Initial support for MAX consent flow. Please see our documentation for instructions on enabling it.
29
- * Add `AppLovinMAX.setCreativeDebuggerEnabled()` API to enable the creative debugger button.
30
- * Revert from using the hardcoded SDK value of 10.1.1 to using +.
31
- * Fix MRec ad expanded event not working on Android.
32
- ## 1.1.10
33
- * Hardcode Android SDK version to 10.1.1.
34
- ## 1.1.9
35
- * Fix React Native version not being passed through to native SDKs.
36
- ## 1.1.8
37
- * Remove need to define Android product flavors in `build.gradle`.
38
- ## 1.1.7
39
- * Fix Android native UI banners rendering issues when mounting / unmounting.
40
- * Add support for setting test device(s) using the advertising identifier (GAID / IDFA) printed in the initialization logs.
41
- ## 1.1.6
42
- * Attempt fix for `loadInterstitial()` or `loadRewardedAd()` due to current Activity being null.
43
- ## 1.1.5
44
- * Fix `removeEventListener()` not working by explicitly calling `remove()`.
45
- ## 1.1.4
46
- * Fix Android banners not working for fast refreshes.
47
- * FIx iOS module's podspec pointing to invalid tag.
48
- ## 1.1.3
49
- * Ensure values such as user id is set before initializing SDK.
50
- * Add workaround for `getCurrentActivity()` returning `null`.
51
- ## 1.1.2
52
- * Fix `ConsentDialogState.UNKNOWN` being returned for `getConsentDialogState()` on iOS.
53
- ## 1.1.1
54
- * Fix `AppLovinMAX.removeEventListener()` crash.
55
- ## 1.1.0
56
- * Add support for native banner / MREC UI components via `<AppLovinMAX.AdView adUnitId={...} adFormat={...} />`.
57
- ## 1.0.0
58
- * 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>