Example optimisation code

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

    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();
        }