Example optimisation code
Below is example code (not production-ready) showing the integration of dynamic floors in MAX.

- Native iOS:
- Native Android: https://github.com/Nefta-io/NeftaMAXAdapter-Android/blob/main/MaxIntegration/src/main/java/com/nefta/max/InterstitialWrapper.java
- Unity: https://github.com/Nefta-io/NeftaMAXAdapter-Unity/blob/main/Assets/AdDemo/InterstitialController.cs
private func GetInsightsAndLoad() {
_isLoadRequested = true
NeftaPlugin._instance.GetBehaviourInsight([AdUnitIdInsightName, FloorPriceInsightName], callback: OnBehaviourInsight)
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
if self._isLoadRequested {
self._recommendedAdUnitId = nil
self._calculatedBidFloor = 0
self.Load()
}
}
}
func OnBehaviourInsight(insights: [String: Insight]) {
_recommendedAdUnitId = nil
_calculatedBidFloor = 0
if let recommendedAdUnitInsight = insights[AdUnitIdInsightName] {
_recommendedAdUnitId = recommendedAdUnitInsight._string
}
if let floorPriceInsight = insights[FloorPriceInsightName] {
_calculatedBidFloor = floorPriceInsight._float
}
print("OnBehaviourInsight for Interstitial recommended AdUnit: \(String(describing: _recommendedAdUnitId)) calculated bid floor:\(_calculatedBidFloor)")
if _isLoadRequested {
Load()
}
}
private func Load() {
_isLoadRequested = false
var adUnitId = DefaultAdUnitId
if let recommendedAdUnitId = _recommendedAdUnitId, !recommendedAdUnitId.isEmpty {
adUnitId = recommendedAdUnitId
}
_interstitial = MAInterstitialAd(adUnitIdentifier: adUnitId)
_interstitial!.delegate = self
_interstitial!.load()
}
func didFailToLoadAd(forAdUnitIdentifier adUnitIdentifier: String, withError error: MAError) {
ALNeftaMediationAdapter.onExternalMediationRequestFail(.interstitial, recommendedAdUnitId: _recommendedAdUnitId, calculatedFloorPrice: _calculatedBidFloor, adUnitIdentifier: adUnitIdentifier, error: error)
SetInfo("didFailToLoadAd \(adUnitIdentifier): \(error)")
_consecutiveAdFails += 1
// As per MAX recommendations, retry with exponentially higher delays up to 64s
// In case you would like to customize fill rate / revenue please contact our customer support
DispatchQueue.main.asyncAfter(deadline: .now() + [0, 2, 4, 8, 32, 64][min(_consecutiveAdFails, 5)]) {
self.GetInsightsAndLoad()
}
}
func didLoad(_ ad: MAAd) {
ALNeftaMediationAdapter.onExternalMediationRequestLoad(.interstitial, recommendedAdUnitId: _recommendedAdUnitId, calculatedFloorPrice: _calculatedBidFloor, ad: ad)
SetInfo("didLoad \(ad)")
_consecutiveAdFails = 0
_showButton.isEnabled = true
}
- (void)GetInsightsAndLoad {
_isLoadRequested = true;
[NeftaPlugin._instance GetBehaviourInsight: @[AdUnitIdInsightName, FloorPriceInsightName] callback: ^(NSDictionary<NSString *, Insight *> *insights) {
[self OnBehaviourInsight: insights];
}];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
if (self.isLoadRequested) {
self.recommendedAdUnitId = nil;
self.calculatedBidFloor = 0;
[self Load];
}
});
}
-(void)OnBehaviourInsight:(NSDictionary<NSString *, Insight *> *)insights {
_recommendedAdUnitId = nil;
_calculatedBidFloor = 0;
Insight* recommendAdUnitInsight = insights[AdUnitIdInsightName];
if (recommendAdUnitInsight != nil) {
_recommendedAdUnitId = recommendAdUnitInsight._string;
}
Insight* floorPriceInsight = insights[FloorPriceInsightName];
if (floorPriceInsight != nil) {
_calculatedBidFloor = floorPriceInsight._float;
}
NSLog(@"OnBehaviourInsight for Interstitial recommended AdUnit: %@ calculated bid floor: %f", _recommendedAdUnitId, _calculatedBidFloor);
if (_isLoadRequested) {
[self Load];
}
}
- (void)Load {
_isLoadRequested = false;
NSString* adUnitId = DefaultAdUnitId;
if (_recommendedAdUnitId != nil && _recommendedAdUnitId.length > 0) {
adUnitId = _recommendedAdUnitId;
}
_interstitial = [[MAInterstitialAd alloc] initWithAdUnitIdentifier: adUnitId];
_interstitial.delegate = self;
[_interstitial loadAd];
}
- (void)didFailToLoadAdForAdUnitIdentifier:(NSString *)adUnitIdentifier withError:(MAError *)error {
[ALNeftaMediationAdapter OnExternalMediationRequestFail: AdTypeInterstitial recommendedAdUnitId: _recommendedAdUnitId calculatedFloorPrice: _calculatedBidFloor adUnitIdentifier: adUnitIdentifier error: error];
[self SetInfo: @"didFailToLoadAdForAdUnitIdentifier %@: %@", adUnitIdentifier, error];
_consecutiveAdFails++;
// As per MAX recommendations, retry with exponentially higher delays up to 64s
// In case you would like to customize fill rate / revenue please contact our customer support
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int[]){ 0, 2, 4, 8, 32, 64 }[MIN(_consecutiveAdFails, 5)] * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self GetInsightsAndLoad];
});
}
- (void)didLoadAd:(MAAd *)ad {
[ALNeftaMediationAdapter OnExternalMediationRequestLoad: AdTypeInterstitial recommendedAdUnitId: _recommendedAdUnitId calculatedFloorPrice: _calculatedBidFloor ad: ad];
[self SetInfo: @"didFailToLoadAdForAdUnitIdentifier %@: %f", ad, ad.revenue];
_consecutiveAdFails = 0;
_showButton.enabled = true;
}
private void GetInsightsAndLoad() {
_isLoadRequested = true;
NeftaPlugin._instance.GetBehaviourInsight(new String[] { AdUnitIdInsightName, FloorPriceInsightName }, this::OnBehaviourInsight);
_handler.postDelayed(() -> {
if (_isLoadRequested) {
_recommendedAdUnitId = null;
_calculatedBidFloor = 0;
Load();
}
}, 5000);
}
private void OnBehaviourInsight(HashMap<String, Insight> insights) {
_recommendedAdUnitId = null;
_calculatedBidFloor = 0;
if (insights.containsKey(AdUnitIdInsightName)) {
_recommendedAdUnitId = insights.get(AdUnitIdInsightName)._string;
}
if (insights.containsKey(FloorPriceInsightName)) {
_calculatedBidFloor = insights.get(FloorPriceInsightName)._float;
}
Log.i(TAG, "OnBehaviourInsights for Interstitial: "+ _recommendedAdUnitId +", calculated bid floor: "+ _calculatedBidFloor);
if (_isLoadRequested) {
Load();
}
}
private void Load() {
_isLoadRequested = false;
String adUnitId = DefaultAdUnitId;
if (_recommendedAdUnitId != null) {
adUnitId = _recommendedAdUnitId;
}
Log.i(TAG, "Loading Interstitial "+ adUnitId);
_interstitialAd = new MaxInterstitialAd(adUnitId);
_interstitialAd.setListener(InterstitialWrapper.this);
_interstitialAd.setRevenueListener(InterstitialWrapper.this);
_interstitialAd.loadAd();
}
@Override
public void onAdLoadFailed(@NonNull String adUnitId, @NonNull MaxError maxError) {
NeftaMediationAdapter.OnExternalMediationRequestFailed(NeftaMediationAdapter.AdType.Interstitial, _recommendedAdUnitId, _calculatedBidFloor, adUnitId, maxError);
Log.i(TAG, "onAdLoadFailed "+ adUnitId);
_loadButton.setEnabled(true);
_showButton.setEnabled(false);
_consecutiveAdFails++;
// As per MAX recommendations, retry with exponentially higher delays up to 64s
// In case you would like to customize fill rate / revenue please contact our customer support
_handler.postDelayed(this::GetInsightsAndLoad, new int[] { 0, 2, 4, 8, 32, 64 } [Math.min(_consecutiveAdFails, 5)] * 1000L);
}
@Override
public void onAdLoaded(@NonNull MaxAd ad) {
NeftaMediationAdapter.OnExternalMediationRequestLoaded(NeftaMediationAdapter.AdType.Interstitial, _recommendedAdUnitId, _calculatedBidFloor, ad);
Log.i(TAG, "onAdLoaded "+ ad.getAdUnitId());
_consecutiveAdFails = 0;
_showButton.setEnabled(true);
}
private void GetInsightsAndLoad()
{
NeftaAdapterEvents.GetBehaviourInsight(new string[] { AdUnitIdInsightName, FloorPriceInsightName }, OnBehaviourInsight);
_fallbackCoroutine = StartCoroutine(LoadFallback());
}
private void OnBehaviourInsight(Dictionary<string, Insight> insights)
{
_recommendedAdUnitId = null;
_calculatedBidFloor = 0;
if (insights.TryGetValue(AdUnitIdInsightName, out var insight))
{
_recommendedAdUnitId = insight._string;
}
if (insights.TryGetValue(FloorPriceInsightName, out insight))
{
_calculatedBidFloor = insight._float;
}
Debug.Log($"OnBehaviourInsight for Interstitial recommended AdUnit: {_recommendedAdUnitId}, calculated bid floor: {_calculatedBidFloor}");
if (_fallbackCoroutine != null)
{
Load();
}
}
private void Load()
{
if (_fallbackCoroutine != null)
{
StopCoroutine(_fallbackCoroutine);
_fallbackCoroutine = null;
}
_selectedAdUnitId = _recommendedAdUnitId ?? _defaultAdUnitId;
MaxSdk.LoadInterstitial(_selectedAdUnitId);
}
private void OnAdFailedEvent(string adUnitId, MaxSdkBase.ErrorInfo errorInfo)
{
NeftaAdapterEvents.OnExternalMediationRequestFailed(NeftaAdapterEvents.AdType.Interstitial, _recommendedAdUnitId, _calculatedBidFloor, adUnitId, errorInfo);
SetStatus($"Load failed: {errorInfo.Message}");
_consecutiveAdFails++;
StartCoroutine(ReTryLoad());
}
private void OnAdLoadedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
{
NeftaAdapterEvents.OnExternalMediationRequestLoaded(NeftaAdapterEvents.AdType.Interstitial, _recommendedAdUnitId, _calculatedBidFloor, adInfo);
SetStatus($"Loaded {adUnitId}: {adInfo.NetworkName}");
_consecutiveAdFails = 0;
_show.interactable = true;
}
private IEnumerator ReTryLoad()
{
// As per MAX recommendations, retry with exponentially higher delays up to 64s
// In case you would like to customize fill rate / revenue please contact our customer support
yield return new WaitForSeconds(new [] { 0, 2, 4, 8, 32, 64 }[Math.Min(_consecutiveAdFails, 5)]);
GetInsightsAndLoad();
}
private IEnumerator LoadFallback()
{
yield return new WaitForSeconds(5f);
_recommendedAdUnitId = null;
_calculatedBidFloor = 0;
Load();
}
Updated 5 days ago