Integration into existing mediation

Multiple Ad SDKs with logic control

In case you have multiple Ad SDKs you will probably want to have some logic to control which SDK offers the ad with the highest bid price. Two of the most common implementations are waterfall (sequential Ad Requests) and header bidding (Simultaneous Ad Requests).

Given the following abstract Ad provider SDK:

public interface IAdProvider
{
	public interface IAdUnit
	{
		float GetPrice();
	}

	void AddOnLoadCompleteListener(Action<IAdUnit> listener);

	void Load();

	void Show();
}

Waterfall

public void LoadAndShowTheBestAdThroughWaterfall()
{
  foreach (var adProvider in _integratedAdProviders)
  {
    _providerWaterfall.Enqueue(adProvider);
  }
  RequestAdFromNextProvider();
}

private void RequestAdFromNextProvider()
{
  if (_providerWaterfall.TryDequeue(out var nextProvider))
  {
    nextProvider.Load(); // we still have more providers to check
    return;
  }

  // all providers have been checked, let's show the ad with highest bid
  ShowBestLoadedAd();
}

private void OnLoadComplete(IAdProvider adProvider, IAdProvider.IAdUnit adUnit)
{
  _loadedAdPerSdk[adProvider] = adUnit;

  RequestAdFromNextProvider();
}

private void ShowBestLoadedAd()
{
  // all providers have been checked, let's show the ad with highest bid
  KeyValuePair<IAdProvider, IAdProvider.IAdUnit> bestProviderAd = new KeyValuePair<IAdProvider, IAdProvider.IAdUnit>(null, null);
  foreach (var providerAd in _loadedAdPerSdk)
  {
    if (bestProviderAd.Value == null || bestProviderAd.Value.GetPrice() < providerAd.Value.GetPrice())
    {
      bestProviderAd = providerAd;
    }
  }
  _loadedAdPerSdk.Clear();
  bestProviderAd.Key.Show();
}

Header bidding

public void LoadAndShowTheBestAdThroughHeaderBidding()
{
  _providersToHeadBid.AddRange(_integratedAdProviders);
  foreach (var adProvider in _providersToHeadBid)
  {
    adProvider.Load();
  }
}

private void RequestAdFromNextProvider()
{
  if (_providerWaterfall.TryDequeue(out var nextProvider))
  {
    nextProvider.Load(); // we still have more providers to check
    return;
  }
}

private void OnLoadComplete(IAdProvider adProvider, IAdProvider.IAdUnit adUnit)
{
  _loadedAdPerSdk[adProvider] = adUnit;
  _providersToHeadBid.Remove(adProvider);

  // if we already received response from all ad providers
  if (_providersToHeadBid.Count == 0)
  {
    ShowBestLoadedAd();
  }
}

private void ShowBestLoadedAd()
{
  // all providers have been checked, let's show the ad with highest bid
  KeyValuePair<IAdProvider, IAdProvider.IAdUnit> bestProviderAd = new KeyValuePair<IAdProvider, IAdProvider.IAdUnit>(null, null);
  foreach (var providerAd in _loadedAdPerSdk)
  {
    if (bestProviderAd.Value == null || bestProviderAd.Value.GetPrice() < providerAd.Value.GetPrice())
    {
      bestProviderAd = providerAd;
    }
  }
  _loadedAdPerSdk.Clear();
  bestProviderAd.Key.Show();
}

We recommend going with the header bidding approach as the bid price can fluctuate whilst we are waiting for the providers in the waterfall to respond one by one. This delay leads to making less optimal decisions.