Preparing Mediated Networks

  • Updated

When you integrate third-party SDKs into your Mobile Property, you are solely responsible for such integrations. You and the third-party SDK provider must ensure compliant data processing and treatment of any end user- or device-based privacy choices or flags.

  • You can download and integrate the MAX mediation adapters into your app in multiple ways:

    Gradle
    AppLovin recommends that you integrate adapters this way. AppLovin’s adapters’ POM files automatically integrate the mediated network’s SDK along with its dependencies.
    Open Source Adapters
    If you require more flexibility in the integration, you can integrate AppLovin’s open source adapters. Android SDK v11.0.0 is required in order to compile. You are responsible for integrating the mediated SDKs and any dependencies they require. You can find these adapters in the AppLovn-MAX-SDK-Android GitHub repository.
    Manual Integration
    Read the manual integration instructions if you want to integrate the adapter artifacts, mediated SDKs, and their dependencies manually.

    Do not change the adapter’s name or package name. If you do so, the MAX SDK will not be able to recognize the adapter and ads will not load.

    Gradle

    Choose which mediated ad networks you want to integrate by checking the boxes below, and this page will display instructions specific to those networks. Then copy the customized Gradle script below to your app-level build.gradle.

    Cordova adds a subsection to the dependencies block of your app-level build.gradle file that begins // SUB-PROJECT DEPENDENCIES START and ends // SUB-PROJECT DEPENDENCIES END. Make sure that when you add the dependencies from the Gradle snippet below to your app-level build.gradle file, that you do so outside (either before or after) that section.

    • // Repos
      repositories {
          google()
          mavenCentral()
      }
      
      dependencies {
          implementation 'com.applovin:applovin-sdk:+'
      }
    • // Repos
      repositories {
          google()
          mavenCentral()
      }
      
      dependencies {
          implementation("com.applovin:applovin-sdk:+")
      }

    Minimum API Level Required

    Nend requires Android API 19 (KitKat 4.4–4.4.4) or higher.

    Migrating to AndroidX

    Integrate AndroidX libraries into your project. Refer to the Migrate to AndroidX guide for more information on how to migrate your project.

    Add Your Google Bidding and Google AdMob / Google Ad Manager App ID

    In your app’s AndroidManifest.xml, add a <meta-data> tag inside the <application> tag. In the example below, replace your-admob-app-id with your Google bidding and Google AdMob / Google Ad Manager App ID.

    <?xml version="1.0" encoding="utf-8"?>
    <manifest … >
      <application … >
        <meta-data
          android:name="com.google.android.gms.ads.APPLICATION_ID"
          android:value="your-admob-app-id"/>
        ⋮
      </application>
    </manifest>

    Google Mobile Ads SDK versions 20.5.0 and newer require that you set the compileSdkVersion of your app to 31 in build.gradle. Google Mobile Ads SDK version 20.4.0.1 is the most recent version that still supports setting compileSdkVersion to 30.

    Use the latest Amazon Publisher Services adapter version to avoid reporting discrepancies.

    Initialize the Amazon SDK

    The Amazon Publisher Services SDK requires that you initialize it outside of MAX SDK:

    // Amazon requires an 'Activity' instance
    AdRegistration.getInstance( "AMAZON_APP_ID", this );
    AdRegistration.setAdNetworkInfo( new DTBAdNetworkInfo( DTBAdNetwork.MAX ) );
    AdRegistration.setMRAIDSupportedVersions( new String[] { "1.0", "2.0", "3.0" } );
    AdRegistration.setMRAIDPolicy( MRAIDPolicy.CUSTOM );

    Load a Banner Ad from Amazon’s SDK

    Amazon leaders (tablet banners) are not supported. Only use Amazon banners when you create slot IDs in the Amazon dashboard.

    To integrate Amazon ads into MAX, you must load the Amazon ad first, then pass the DTBAdResponse or AdError into the instance of MaxAdView by calling MaxAdView#setLocalExtraParameter() before you load the MAX ad.

    For auto-refreshing banner ads you only need to load the ad once.

    • class ExampleActivity
              extends Activity
      {
        ⋮
      
        private void loadAd()
        {
          String amazonAdSlotId;
          MaxAdFormat adFormat;
      
          if ( AppLovinSdkUtils.isTablet( getApplicationContext() ) )
          {
            amazonAdSlotId = "Amazon-leader-slot-ID";
            adFormat = MaxAdFormat.LEADER;
          }
          else
          {
            amazonAdSlotId = "Amazon-banner-slot-ID";
            adFormat = MaxAdFormat.BANNER;
          }
      
          // Raw size will be 320x50 for BANNERs on phones, and 728x90 for LEADERs on tablets
          AppLovinSdkUtils.Size rawSize = adFormat.getSize();
          DTBAdSize size = new DTBAdSize( rawSize.getWidth(), rawSize.getHeight(), amazonAdSlotId );
      
          DTBAdRequest adLoader = new DTBAdRequest();
          adLoader.setSizes( size );
          adLoader.loadAd( new DTBAdCallback()
          {
            @Override
            public void onSuccess(@NonNull final DTBAdResponse dtbAdResponse)
            {
              // 'adView' is your instance of MaxAdView
              adView.setLocalExtraParameter( "amazon_ad_response", dtbAdResponse );
              adView.loadAd();
            }
            
            @Override
            public void onFailure(@NonNull final AdError adError)
            {
              // 'adView' is your instance of MaxAdView
              adView.setLocalExtraParameter( "amazon_ad_error", adError );
              adView.loadAd();
            }
          } );
        }
      }
    • class ExampleActivity : Activity()
      {
        private val adView: MaxAdView? = null
      
        private fun loadAd()
        {
          val amazonAdSlotId: String
          val adFormat: MaxAdFormat
      
          if (AppLovinSdkUtils.isTablet(applicationContext))
          {
            amazonAdSlotId = "Amazon-leader-slot-ID"
            adFormat = MaxAdFormat.LEADER
          }
          else
          {
            amazonAdSlotId = "Amazon-banner-slot-ID"
            adFormat = MaxAdFormat.BANNER
          }
      
          // Raw size will be 320x50 for BANNERs on phones, and 728x90 for LEADERs on tablets
          val rawSize = adFormat.size
          val size = DTBAdSize(rawSize.width, rawSize.height, amazonAdSlotId)
      
          val adLoader = DTBAdRequest()
          adLoader.setSizes(size)
          adLoader.loadAd(object : DTBAdCallback
          {
            override fun onSuccess(dtbAdResponse: DTBAdResponse)
            {
              // 'adView' is your instance of MaxAdView
              adView?.setLocalExtraParameter("amazon_ad_response", dtbAdResponse)
              adView?.loadAd()
            }
      
            override fun onFailure(adError: AdError)
            {
              // 'adView' is your instance of MaxAdView
              adView?.setLocalExtraParameter("amazon_ad_error", adError)
              adView?.loadAd()
            }
          })
        }
      }

    Load an MREC Ad from Amazon’s SDK

    To integrate Amazon MRECs into MAX, you must load the Amazon ad first, then pass the DTBAdResponse or AdError into the instance of MaxAdView by calling MaxAdView#setLocalExtraParameter() before you load the MAX ad.

    • class ExampleActivity
              extends Activity
      {
        ⋮
        private void loadAd()
        {
          String amazonAdSlotId;
      
          DTBAdRequest adLoader = new DTBAdRequest();
          adLoader.setSizes( new DTBAdSize( 300, 250, amazonAdSlotId ) );
          adLoader.loadAd( new DTBAdCallback()
          {
            @Override
            public void onSuccess(@NonNull final DTBAdResponse dtbAdResponse)
            {
              // 'adView' is your instance of MaxAdView
              adView.setLocalExtraParameter( "amazon_ad_response", dtbAdResponse );
              adView.loadAd();
            }
      
            @Override
            public void onFailure(@NonNull final AdError adError)
            {
              // 'adView' is your instance of MaxAdView
              adView.setLocalExtraParameter( "amazon_ad_error", adError );
              adView.loadAd();
            }
          } );
        }
      }
    • class ExampleActivity : Activity()
      {
        private val adView: MaxAdView? = null
      
        private fun loadAd()
        {
          val amazonAdSlotId: String
      
          val adLoader = DTBAdRequest()
          adLoader.setSizes(DTBAdSize(300, 250, amazonAdSlotId))
          adLoader.loadAd(object : DTBAdCallback
          {
            override fun onSuccess(dtbAdResponse: DTBAdResponse)
            {
              // 'adView' is your instance of MaxAdView
              adView!!.setLocalExtraParameter("amazon_ad_response", dtbAdResponse)
              adView.loadAd()
            }
      
            override fun onFailure(adError: AdError)
            {
              // 'adView' is your instance of MaxAdView
              adView!!.setLocalExtraParameter("amazon_ad_error", adError)
              adView.loadAd()
            }
          })
        }
      }

    Load an Interstitial Ad from Amazon’s SDK

    To integrate Amazon interstitial ads into MAX, you must load the Amazon ad first, then pass the DTBAdResponse or AdError into the instance of MaxInterstitialAd by calling MaxInterstitialAd#setLocalExtraParameter() before you load the MAX ad.

    You must load and pass the Amazon DTBAdResponse or DTBAdErrorInfo into the MaxInterstitialAd instance only once per session.

    • class ExampleActivity
             extends Activity
      {
        private static MaxInterstitialAd interstitialAd; // static to ensure only one instance exists
        private static boolean           isFirstLoad = true;
      
        private void loadAd()
        {
          if ( isFirstLoad )
          {
            isFirstLoad = false;
      
            if ( interstitialAd == null )
            {
              interstitialAd = new MaxInterstitialAd( "MAX-inter-ad-unit-ID", this );
            }
      
            DTBAdRequest adLoader = new DTBAdRequest();
            adLoader.setSizes( new DTBAdSize.DTBInterstitialAdSize( "Amazon-inter-slot-ID" ) );
            adLoader.loadAd( new DTBAdCallback()
            {
              @Override
              public void onSuccess(@NonNull final DTBAdResponse dtbAdResponse)
              {
                // 'interstitialAd' is your instance of MaxInterstitialAd
                interstitialAd.setLocalExtraParameter( "amazon_ad_response", dtbAdResponse );
                interstitialAd.loadAd();
              }
              
              @Override
              public void onFailure(@NonNull final AdError adError)
              {
                // 'interstitialAd' is your instance of MaxInterstitialAd
                interstitialAd.setLocalExtraParameter( "amazon_ad_error", adError );
                interstitialAd.loadAd();
              }
            } );
          }
          else
          {
            interstitialAd.loadAd();
          }
        }
      }
    • class ExampleActivity : Activity()
      {
        private var interstitialAd: MaxInterstitialAd? = null // static to ensure only one instance exists
        private var isFirstLoad = true
      
        private fun loadAd()
        {
          if (isFirstLoad)
          {
            isFirstLoad = false
      
            if (interstitialAd == null)
            {
              interstitialAd = MaxInterstitialAd("MAX-inter-ad-unit-ID", this)
            }
      
            val adLoader = DTBAdRequest()
            adLoader.setSizes(DTBAdSize.DTBInterstitialAdSize("Amazon-inter-slot-ID"))
            adLoader.loadAd(object : DTBAdCallback
            {
              override fun onSuccess(dtbAdResponse: DTBAdResponse)
              {
                // 'interstitialAd' is your instance of MaxInterstitialAd
                interstitialAd!!.setLocalExtraParameter("amazon_ad_response", dtbAdResponse)
                interstitialAd!!.loadAd()
              }
      
              override fun onFailure(adError: AdError)
              {
                // 'interstitialAd' is your instance of MaxInterstitialAd
                interstitialAd!!.setLocalExtraParameter("amazon_ad_error", adError)
                interstitialAd!!.loadAd()
              }
            })
          }
          else
          {
            interstitialAd!!.loadAd()
          }
        }
      }

    Load a Video Interstitial Ad from Amazon’s SDK

    To integrate Amazon video interstitial ads into MAX, you must load the Amazon ad first, then pass the DTBAdResponse or AdError into the instance of MaxInterstitialAd by calling MaxInterstitialAd#setLocalExtraParameter() before you load the MAX ad.

    You must load and pass the Amazon DTBAdResponse or DTBAdErrorInfo into the MaxInterstitialAd instance only once per session.

    • class ExampleActivity
             extends Activity
      {
        private static MaxInterstitialAd interstitialAd; // static to ensure only one instance exists
        private static boolean           isFirstLoad = true;
      
        private void loadAd()
        {
          if ( isFirstLoad )
          {
            isFirstLoad = false;
      
            if ( interstitialAd == null )
            {
              interstitialAd = new MaxInterstitialAd( "MAX-inter-ad-unit-ID", this );
            }
      
            DTBAdRequest adLoader = new DTBAdRequest();
      
            // Switch video player width and height values(320, 480) depending on device orientation
            adLoader.setSizes( new DTBAdSize.DTBVideo(320, 480, "Amazon-video-inter-slot-ID") );
            adLoader.loadAd( new DTBAdCallback()
            {
              @Override
              public void onSuccess(@NonNull final DTBAdResponse dtbAdResponse)
              {
                // 'interstitialAd' is your instance of MaxInterstitialAd
                interstitialAd.setLocalExtraParameter( "amazon_ad_response", dtbAdResponse );
                interstitialAd.loadAd();
              }
      
              @Override
              public void onFailure(@NonNull final AdError adError)
              {
                // 'interstitialAd' is your instance of MaxInterstitialAd
                interstitialAd.setLocalExtraParameter( "amazon_ad_error", adError );
                interstitialAd.loadAd();
              }
            } );
          }
          else
          {
            interstitialAd.loadAd();
          }
        }
      }
    • class ExampleActivity : Activity()
      {
        private var interstitialAd: MaxInterstitialAd? = null // static to ensure only one instance exists
        private var isFirstLoad = true
      
        private fun loadAd()
        {
          if (isFirstLoad)
          {
            isFirstLoad = false
      
            if (interstitialAd == null)
            {
              interstitialAd = MaxInterstitialAd("MAX-inter-ad-unit-iD", this)
            }
      
            val adLoader = DTBAdRequest()
      
            // Switch video player width and height values(320, 480) depending on device orientation
            adLoader.setSizes(DTBAdSize.DTBVideo(320, 480, "Amazon-video-inter-slot-ID"))
            adLoader.loadAd(object : DTBAdCallback
            {
              override fun onSuccess(dtbAdResponse: DTBAdResponse)
              {
                // 'interstitialAd' is your instance of MaxInterstitialAd
                interstitialAd!!.setLocalExtraParameter("amazon_ad_response", dtbAdResponse)
                interstitialAd!!.loadAd()
              }
      
              override fun onFailure(adError: AdError)
              {
                // 'interstitialAd' is your instance of MaxInterstitialAd
                interstitialAd!!.setLocalExtraParameter("amazon_ad_error", adError)
                interstitialAd!!.loadAd()
              }
            })
          }
          else
          {
            interstitialAd!!.loadAd()
          }
        }
      }

    Load a Rewarded Video Ad from Amazon’s SDK

    To integrate Amazon rewarded videos into MAX, first load the Amazon ad, then pass the DTBAdResponse or AdError into the instance of MaxRewardedAd by calling MaxRewardedAd#setLocalExtraParameter() before you load the MAX ad.

    You must load and pass the Amazon DTBAdResponse or AdError into the MaxRewardedAd instance only once per session.

    • class ExampleActivity
              extends Activity
      {
        private static MaxRewardedAd rewardedAd; // static to ensure only one instance exists
        private static boolean       isFirstLoad = true;
      
        private void loadAd()
        {
          if ( isFirstLoad )
          {
            isFirstLoad = false;
      
            if ( rewardedAd == null )
            {
              rewardedAd = MaxRewardedAd.getInstance( "MAX-rewarded-ad-unit-ID", this );
            }
      
            DTBAdRequest adLoader = new DTBAdRequest();
      
            // Switch video player width and height values(320, 480) depending on device orientation
            adLoader.setSizes( new DTBAdSize.DTBVideo( 320, 480, "Amazon-video-rewarded-slot-ID" ) );
            adLoader.loadAd( new DTBAdCallback()
            {
              @Override
              public void onSuccess(@NonNull final DTBAdResponse dtbAdResponse)
              {
                // 'rewardedAd' is your instance of MaxRewardedAd
                rewardedAd.setLocalExtraParameter( "amazon_ad_response", dtbAdResponse );
                rewardedAd.loadAd();
              }
      
              @Override
              public void onFailure(@NonNull final AdError adError)
              {
                // 'rewardedAd' is your instance of MaxRewardedAd
                rewardedAd.setLocalExtraParameter( "amazon_ad_error", adError );
                rewardedAd.loadAd();
              }
            } );
          }
          else
          {
            rewardedAd.loadAd();
          }
        }
      }
    • class ExampleActivity
              extends Activity
      {
        private static MaxRewardedAd rewardedAd; // static to ensure only one instance exists
        private static boolean       isFirstLoad = true;
      
        private void loadAd()
        {
          if ( isFirstLoad )
          {
            isFirstLoad = false;
      
            if ( rewardedAd == null )
            {
              rewardedAd = MaxRewardedAd.getInstance( "MAX-rewarded-ad-unit-ID", this );
            }
      
            DTBAdRequest adLoader = new DTBAdRequest();
      
            // Switch video player width and height values(320, 480) depending on device orientation
            adLoader.setSizes( new DTBAdSize.DTBVideo( 320, 480, "Amazon-video-rewarded-slot-ID" ) );
            adLoader.loadAd( new DTBAdCallback()
            {
              @Override
              public void onSuccess(@NonNull final DTBAdResponse dtbAdResponse)
              {
                // 'rewardedAd' is your instance of MaxRewardedAd
                rewardedAd.setLocalExtraParameter( "amazon_ad_response", dtbAdResponse );
                rewardedAd.loadAd();
              }
      
              @Override
              public void onFailure(@NonNull final AdError adError)
              {
                // 'rewardedAd' is your instance of MaxRewardedAd
                rewardedAd.setLocalExtraParameter( "amazon_ad_error", adError );
                rewardedAd.loadAd();
              }
            } );
          }
          else
          {
            rewardedAd.loadAd();
          }
        }
      }

    Testing Amazon Publisher Services

    AppLovin recommends that you enable test mode for Amazon’s SDK to receive test ads. You can do this with the following calls:

    AdRegistration.enableTesting( true );
    AdRegistration.enableLogging( true );

    To filter your waterfalls to contain only Amazon ads, navigate to Select Live Network in the Mediation Debugger and select the Amazon network.

    Enable Google Ad Manager

    In your app’s AndroidManifest.xml, add a <meta-data> tag inside the <application> tag, as in the example below:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest … >
      <application … >
        <meta-data
            android:name="com.google.android.gms.ads.AD_MANAGER_APP"
            android:value="true"/>
        ⋮
      </application>
    </manifest>

    Meta Audience Network Data Processing Options

    If you do not want to enable Limited Data Use (LDU) mode, pass SetDataProcessingOptions() an empty string array:

    • import com.facebook.ads.AdSettings;
      ⋮
      AdSettings.setDataProcessingOptions( new String[] {} );
      ⋮
      // Initialize MAX SDK
    • import com.facebook.ads.AdSettings
      ⋮
      AdSettings.setDataProcessingOptions( arrayOf<String>() )
      ⋮
      // Initialize MAX SDK

    To enable LDU for users and specify user geography, call SetDataProcessingOptions() in a form like this:

    • import com.facebook.ads.AdSettings;
      ⋮
      AdSettings.setDataProcessingOptions( new String[] {"LDU"}, 1, 1000 );
      ⋮
      // Initialize MAX SDK
    • import com.facebook.ads.AdSettings
      ⋮
      AdSettings.setDataProcessingOptions( arrayOf("LDU"), 1, 1000 )
      ⋮
      // Initialize MAX SDK

    Meta Audience Network Data Processing Options for Users in California

    For information about how to implement Meta Audience Network’s “Limited Data Use” flag in California, visit the Meta for Developers documentation.

    Android Manifest Merging Errors

    Several network SDKs use the <queries> element in their bundled Android Manifest files. If you are on an incompatible version of the Android Gradle plugin, this will cause one of the following build errors:

    • com.android.builder.internal.aapt.v2.Aapt2Exception: Android resource linking failed
      error: unexpected element <queries> found in <manifest>.
    • Missing 'package' key attribute on element package at [:com.my.target.mytarget-sdk-5.11.3:]
      AndroidManifest Validation failed

    To fix this error, upgrade to one of the following versions of the Android Gradle plugin that supports the <queries> element:

    Upgrade the Android Gradle Plugin, not the Gradle Build Tools.

    Current Android Gradle Plugin Version Version that Supports <queries> Element
    4.1.* All
    4.0.* 4.0.1+
    3.6.* 3.6.4+
    3.5.* 3.5.4+
    3.4.* 3.4.3+
    3.3.* 3.3.3+
  • You can download and integrate the MAX mediation adapters into your app in multiple ways:

    CocoaPods
    AppLovin recommends that you integrate adapters this way. AppLovin’s adapters’ pods automatically integrate the mediated network’s SDK along with its dependencies.
    Open Source Adapters
    If you require more flexibility in the integration, you can integrate AppLovin’s open source adapters. iOS SDK v11.0.0 is required in order to compile. You are responsible for integrating the mediated SDKs and any dependencies they require. You can find these adapters in the AppLovin-MAX-SDK-iOS GitHub repository.
    Manual Integration
    Read the manual integration instructions if you want to integrate the adapter artifacts, mediated SDKs, and their dependencies manually.

    Do not change the adapter’s name. If you do so, the MAX SDK will not be able to recognize the adapter and ads will not load.

    CocoaPods

    Choose which mediated ad networks you want to integrate by checking the boxes below, and this page will display instructions specific to those networks. Copy the customized CocoaPods script below to your Podfile.

     

    Starting from Pangle iOS adapter version 4.9.1.0.0, Pangle is no longer available in Chinese Mainland. If you wish to monetize Chinese Mainland traffic, please set up the CSJ network and add the CSJ adapter. For global traffic excluding Chinese Mainland, you can continue to use Pangle for monetization.

    Swift Build Settings

    To support Swift for iOS versions below 12.2, in the main target of your Xcode project select File > Build Settings and set Always Embed Swift Standard Libraries to Yes.

    Setting: Always Embed Swift Standard Libraries. AppLovin MAX Demo App: Yes.

    App Delegate window Property

    Do not remove the window property of your App Delegate file as this might crash InMobi’s SDK.

    • @property (nonatomic, strong) UIWindow *window;
    • var window: UIWindow?

    Meta Audience Network Data Processing Options

    If you do not want to enable Limited Data Use (LDU) mode, pass SetDataProcessingOptions() an empty array:

    • #import <FBAudienceNetwork/FBAudienceNetwork.h>
      ⋮
      [FBAdSettings setDataProcessingOptions: @[]];
      ⋮
      // Initialize MAX SDK
    • import FBAudienceNetwork
      ⋮
      FBAdSettings.setDataProcessingOptions([])
      ⋮
      // Initialize MAX SDK

    To enable LDU for users and specify user geography, call SetDataProcessingOptions() in a form like this:

    • #import <FBAudienceNetwork/FBAudienceNetwork.h>
      ⋮
      [FBAdSettings setDataProcessingOptions: @[@"LDU"] country: 1 state: 1000];
      ⋮
      // Initialize MAX SDK
    • import FBAudienceNetwork
      ⋮
      FBAdSettings.setDataProcessingOptions(["LDU"], country: 1, state: 1000)
      ⋮
      // Initialize MAX SDK

    Meta Audience Network Data Processing Options for Users in California

    For information about how to implement Meta Audience Network’s “Limited Data Use” flag in California, visit the Meta for Developers documentation.

    Meta Preparing for iOS 14.5 and Above

    Audience Network SDK 6.2.1 was released on January 11, 2021. This version has these important requirements:

    • Implement the setAdvertiserTrackingEnabled flag, irrespective of the use of mediation, to inform Meta whether to use the data to deliver personalized ads.
    • Add the SKAdNetwork IDs that Meta suggests to the Xcode project’s Info.plist in order for advertisers to measure the success of ad campaigns. Refer to the SKAdNetwork documentation for integration instructions.
    • [sdk initializeSdkWithCompletionHandler:^(ALSdkConfiguration *sdkConfiguration)
      {
         if ( @available(iOS 14.5, *) )
         {
           // Note that App transparency tracking authorization can be checked via `sdkConfiguration.appTrackingTransparencyStatus`
           // 1. Set Meta ATE flag here, THEN
         }
      
         // 2. Load ads
      }];
    • sdk.initializeSdk { (sdkConfiguration: ALSdkConfiguration) in
      
        if #available(iOS 14.5, *)
        {
          // Note that App transparency tracking authorization can be checked via `sdkConfiguration.appTrackingTransparencyStatus`
          // 1. Set Meta ATE flag here, THEN
        }
        
        // 2. Load ads
      }

    Add Your Google Bidding and Google AdMob / Google Ad Manager App ID

    In your app’s Info.plist, add a GADApplicationIdentifier key with a String value of your Google bidding and Google AdMob / Google Ad Manager App ID.

    GADApplicationIdentifier (String): <YOUR_ADMOB_APP_ID>

    Use the latest Amazon Publisher Services adapter version to avoid reporting discrepancies.

    Initialize the Amazon SDK

    The Amazon Publisher Services SDK requires that you initialize it outside of MAX SDK:

    [[DTBAds sharedInstance] setAppKey: appId];
    DTBAdNetworkInfo *adNetworkInfo = [[DTBAdNetworkInfo alloc] initWithNetworkName: DTBADNETWORK_MAX];
    [DTBAds sharedInstance].mraidCustomVersions = @[@"1.0", @"2.0", @"3.0"];
    [[DTBAds sharedInstance] setAdNetworkInfo: adNetworkInfo];
    [DTBAds sharedInstance].mraidPolicy = CUSTOM_MRAID;

    Load a Banner Ad from Amazon’s SDK

    To integrate Amazon banner ads into MAX, you must load the Amazon ad first, then pass the DTBAdResponse or DTBAdErrorInfo into the instance of MAAdView by calling -[MAAdView setLocalExtraParameterForKey:value:] before you load the MAX ad.

    For auto-refreshing banner ads you only need to load the ad once.

    • @interface ExampleViewController ()<DTBAdCallback>
      ⋮
      @end
      
      @implementation ExampleViewController
      
      - (void)viewDidLoad
      {
        [super viewDidLoad];
      
        NSString *amazonAdSlotId;
        MAAdFormat *adFormat;
      
        if ( UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad )
        {
          amazonAdSlotId = @"Amazon-leader-slot-ID";
          adFormat = MAAdFormat.leader;
        }
        else
        {
          amazonAdSlotId = @"Amazon-banner-slot-ID";
          adFormat = MAAdFormat.banner;
        }
      
        CGSize rawSize = adFormat.size;
        DTBAdSize *size = [[DTBAdSize alloc] initBannerAdSizeWithWidth: rawSize.width
                                                                height: rawSize.height
                                                           andSlotUUID: amazonAdSlotId];
      
        DTBAdLoader *adLoader = [[DTBAdLoader alloc] init];
        [adLoader setAdSizes: @[size]];
        [adLoader loadAd: self];
      }
      
      - (void)onSuccess:(DTBAdResponse *)adResponse
      {
        // 'adView' is your instance of MAAdView
        [self.adView setLocalExtraParameterForKey: @"amazon_ad_response" value: adResponse];
        [self.adView loadAd];
      }
      
      - (void)onFailure:(DTBAdError)error dtbAdErrorInfo:(DTBAdErrorInfo *)errorInfo
      {
        // 'adView' is your instance of MAAdView
        [self.adView setLocalExtraParameterForKey: @"amazon_ad_error" value: errorInfo];
        [self.adView loadAd];
      }
      
      @end
    • import AppLovinSDK
      import DTBiOSSDK
      
      class ExampleViewController: UIViewController
      {
        override func viewDidLoad()
        {
          super.viewDidLoad()
      
          let amazonAdSlotId: String
          let adFormat: MAAdFormat
      
          if UIDevice.current.userInterfaceIdiom == .pad
          {
            amazonAdSlotId = "Amazon-leader-slot-ID"
            adFormat = MAAdFormat.leader
          }
          else
          {
            amazonAdSlotId = "Amazon-banner-slot-ID"
            adFormat = MAAdFormat.banner
          }
      
          let rawSize = adFormat.size
          let size = DTBAdSize(bannerAdSizeWithWidth: Int(rawSize.width),
                               height: Int(rawSize.height),
                               andSlotUUID: amazonAdSlotId)!
      
          let adLoader = DTBAdLoader()
          adLoader.setAdSizes([size])
          adLoader.loadAd(self)
        }
      }
      
      extension ExampleViewController: DTBAdCallback
      {
        func onSuccess(_ adResponse: DTBAdResponse!)
        {
          // 'adView' is your instance of MAAdView
          adView.setLocalExtraParameterForKey("amazon_ad_response", value: adResponse)
          adView.loadAd()
        }
      
        func onFailure(_ error: DTBAdError, dtbAdErrorInfo: DTBAdErrorInfo!)
        {
          // 'adView' is your instance of MAAdView
          adView.setLocalExtraParameterForKey("amazon_ad_error", value:dtbAdErrorInfo)
          adView.loadAd()
        }
      }

    Load an MREC Ad from Amazon’s SDK

    To integrate Amazon MRECs into MAX, you must load the Amazon ad first, then pass the DTBAdResponse or DTBAdErrorInfo into the instance of MAAdView by calling -[MAAdView setLocalExtraParameterForKey:value:] before you load the MAX ad.

    • @interface ExampleViewController ()<DTBAdCallback>
      ⋮
      @end
      
      @implementation ExampleViewController
      
      - (void)viewDidLoad
      {
        [super viewDidLoad];
      
        NSString *amazonAdSlotId;
        DTBAdLoader *adLoader = [[DTBAdLoader alloc] init];
        [adLoader setAdSizes: [[DTBAdSize alloc] initBannerAdSizeWithWidth: 300
                                                                height: 250
                                                           andSlotUUID: amazonAdSlotId]];
        [adLoader loadAd: self];
      }
      
      - (void)onSuccess:(DTBAdResponse *)adResponse
      {
        // 'adView' is your instance of MAAdView
        [self.adView setLocalExtraParameterForKey: @"amazon_ad_response" value: adResponse];
        [self.adView loadAd];
      }
      
      - (void)onFailure:(DTBAdError)error dtbAdErrorInfo:(DTBAdErrorInfo *)errorInfo
      {
        // 'adView' is your instance of MAAdView
        [self.adView setLocalExtraParameterForKey: @"amazon_ad_error" value: errorInfo];
        [self.adView loadAd];
      }
      
      @end
    • import AppLovinSDK
      import DTBiOSSDK
      
      class ExampleViewController: UIViewController
      {
        override func viewDidLoad()
        {
          super.viewDidLoad()
      
          let amazonAdSlotId: String
      
          let adLoader = DTBAdLoader()
          adLoader.setAdSizes([DTBAdSize(bannerAdSizeWithWidth: 300,
                               height: 250,
                               andSlotUUID: amazonAdSlotId)!])
          adLoader.loadAd(self)
        }
      }
      
      extension ExampleViewController: DTBAdCallback
      {
        func onSuccess(_ adResponse: DTBAdResponse!)
        {
          // 'adView' is your instance of MAAdView
          adView.setLocalExtraParameterForKey("amazon_ad_response", value: adResponse)
          adView.loadAd()
        }
      
        func onFailure(_ error: DTBAdError, dtbAdErrorInfo: DTBAdErrorInfo!)
        {
          // 'adView' is your instance of MAAdView
          adView.setLocalExtraParameterForKey("amazon_ad_error", value:dtbAdErrorInfo)
          adView.loadAd()
        }
      }

    Load an Interstitial Ad from Amazon’s SDK

    To integrate Amazon interstitial ads into MAX, you must load the Amazon ad first, then pass the DTBAdResponse or DTBAdErrorInfo into the instance of MAInterstitialAd by calling -[MAInterstitialAd setLocalExtraParameterForKey:value:] before you load the MAX ad.

    You must load and pass the Amazon DTBAdResponse or DTBAdErrorInfo into the MAInterstitialAd instance only once per session.

    • #import <AppLovinSDK/AppLovinSDK.h>
      #import <DTBiOSSDK/DTBiOSSDK.h>
      
      @interface ExampleViewController ()<DTBAdCallback>
      ⋮
      @end
      
      @implementation ExampleViewController
      static MAInterstitialAd *interstitialAd;
      static BOOL isFirstLoad;
      
      + (void)initialize
      {
        [super initialize];
      
        interstitialAd = [[MAInterstitialAd alloc] initWithAdUnitIdentifier: @"MAX-inter-ad-unit-ID"];
        isFirstLoad = YES;
      }
      
      - (void)loadAd
      {
        // If first load - load ad from Amazon's SDK, then load ad for MAX
        if ( isFirstLoad )
        {
          isFirstLoad = NO;
      
          DTBAdLoader *adLoader = [[DTBAdLoader alloc] init];
          [adLoader setAdSizes: @[
            [[DTBAdSize alloc] initInterstitialAdSizeWithSlotUUID: @"Amazon-inter-slot-ID"]
          ]];
          [adLoader loadAd: self];
        }
        else
        {
          [interstitialAd loadAd];
        }
      }
      
      - (void)onSuccess:(DTBAdResponse *)adResponse
      {
        // 'interstitialAd' is your instance of MAInterstitialAd
        [interstitialAd setLocalExtraParameterForKey: @"amazon_ad_response" value: adResponse];
        [interstitialAd loadAd];
      }
      
      - (void)onFailure:(DTBAdError)error dtbAdErrorInfo:(DTBAdErrorInfo *)errorInfo
      {
        // 'interstitialAd' is your instance of MAInterstitialAd
        [interstitialAd setLocalExtraParameterForKey: @"amazon_ad_error" value: errorInfo];
        [interstitialAd loadAd];
      }
      
      @end
    • import AppLovinSDK
      import DTBiOSSDK
      
      class ExampleViewController: UIViewController
      {
        private static var interstitialAd = MAInterstitialAd(adUnitIdentifier: "MAX-inter-ad-unit-ID")
        private static var isFirstLoad = true
      
        func loadAd()
        {
          // If first load - load ad from Amazon's SDK, then load ad for MAX
          if Self.isFirstLoad
          {
            Self.isFirstLoad = false
      
            let adLoader = DTBAdLoader()
            adLoader.setAdSizes([DTBAdSize(interstitialAdSizeWithSlotUUID: "Amazon-inter-slot-ID")!])
            adLoader.loadAd(self)
          }
          else
          {
            Self.interstitialAd.load()
          }
        }
      }
      
      extension ExampleViewController: DTBAdCallback
      {
        func onSuccess(_ adResponse: DTBAdResponse!)
        {
          // 'interstitialAd' is your instance of MAInterstitialAd
          Self.interstitialAd.setLocalExtraParameterForKey("amazon_ad_response", value: adResponse)
          Self.interstitialAd.load()
        }
      
        func onFailure(_ error: DTBAdError, dtbAdErrorInfo: DTBAdErrorInfo!)
        {
          // 'interstitialAd' is your instance of MAInterstitialAd
          Self.interstitialAd.setLocalExtraParameterForKey("amazon_ad_error", value: dtbAdErrorInfo)
          Self.interstitialAd.load()
        }
      }

    Load a Video Interstitial Ad from Amazon’s SDK

    To integrate Amazon interstitial ads into MAX, you must load the Amazon ad first, then pass the DTBAdResponse or DTBAdErrorInfo into the instance of MAInterstitialAd by calling -[MAInterstitialAd setLocalExtraParameterForKey:value:] before you load the MAX ad.

    You must load and pass the Amazon DTBAdResponse or DTBAdErrorInfo into the MAInterstitialAd instance only once per session.

    • #import <AppLovinSDK/AppLovinSDK.h>
      #import <DTBiOSSDK/DTBiOSSDK.h>
      
      @interface ExampleViewController ()<DTBAdCallback>
      ⋮
      @end
      
      @implementation ExampleViewController
      static MAInterstitialAd *interstitialAd;
      static BOOL isFirstLoad;
      
      + (void)initialize
      {
        [super initialize];
      
        interstitialAd = [[MAInterstitialAd alloc] initWithAdUnitIdentifier: @"MAX-inter-ad-unit-ID"];
        isFirstLoad = YES;
      }
      
      - (void)loadAd
      {
        // If first load - load ad from Amazon's SDK, then load ad for MAX
        if ( isFirstLoad )
        {
          isFirstLoad = NO;
      
          DTBAdLoader *adLoader = [[DTBAdLoader alloc] init];
      
          // Switch video player width and height values(320, 480) depending on device orientation
          [adLoader setAdSizes: @[
            [[DTBAdSize alloc] initVideoAdSizeWithPlayerWidth: 320 height: 480 andSlotUUID:@"Amazon-video-inter-slot-ID"]
          ]];
          [adLoader loadAd: self];
        }
        else
        {
          [interstitialAd loadAd];
        }
      }
      
      - (void)onSuccess:(DTBAdResponse *)adResponse
      {
        // 'interstitialAd' is your instance of MAInterstitialAd
        [interstitialAd setLocalExtraParameterForKey: @"amazon_ad_response" value: adResponse];
        [interstitialAd loadAd];
      }
      
      - (void)onFailure:(DTBAdError)error dtbAdErrorInfo:(DTBAdErrorInfo *)errorInfo
      {
        // 'interstitialAd' is your instance of MAInterstitialAd
        [interstitialAd setLocalExtraParameterForKey: @"amazon_ad_error" value: errorInfo];
        [interstitialAd loadAd];
      }
      
      @end
    • import AppLovinSDK
      import DTBiOSSDK
      
      class ExampleViewController: UIViewController
      {
        private static var interstitialAd = MAInterstitialAd(adUnitIdentifier: "MAX-inter-ad-unit-ID")
        private static var isFirstLoad = true
      
        func loadAd()
        {
          // If first load - load ad from Amazon's SDK, then load ad for MAX
          if Self.isFirstLoad
          {
            Self.isFirstLoad = false
            let adLoader = DTBAdLoader()
      
            // Switch video player width and height values(320, 480) depending on device orientation
            adLoader.setAdSizes([DTBAdSize(videoAdSizeWithPlayerWidth: 320, height: 480, andSlotUUID: "Amazon-video-inter-slot-ID")!])
            adLoader.loadAd(self)
          }
          else
          {
            Self.interstitialAd.load()
          }
        }
      }
      
      extension ExampleViewController: DTBAdCallback
      {
        func onSuccess(_ adResponse: DTBAdResponse!)
        {
          // 'interstitialAd' is your instance of MAInterstitialAd
          Self.interstitialAd.setLocalExtraParameterForKey("amazon_ad_response", value: adResponse)
          Self.interstitialAd.load()
        }
      
        func onFailure(_ error: DTBAdError, dtbAdErrorInfo: DTBAdErrorInfo!)
        {
          // 'interstitialAd' is your instance of MAInterstitialAd
          Self.interstitialAd.setLocalExtraParameterForKey("amazon_ad_error", value: dtbAdErrorInfo)
          Self.interstitialAd.load()
        }
      }

    Load a Rewarded Video Ad from Amazon’s SDK

    To integrate Amazon rewarded videos into MAX, you must load the Amazon ad first, then pass the DTBAdResponse or DTBAdErrorInfo into the instance of MARewardedAd by calling -[MARewardedAd setLocalExtraParameterForKey:value:] before you load the MAX ad.

    You must load and pass the Amazon DTBAdResponse or DTBAdErrorInfo into the MARewardedAd instance only once.

    • #import <AppLovinSDK/AppLovinSDK.h>
      #import <DTBiOSSDK/DTBiOSSDK.h>
      
      @interface ExampleViewController ()<DTBAdCallback>
      ⋮
      @end
      
      @implementation ExampleViewController
      static MARewardedAd *rewardedAd;
      static BOOL isFirstLoad;
      
      + (void)initialize
      {
        [super initialize];
      
        rewardedAd = [MARewardedAd sharedWithAdUnitIdentifier: @"MAX-rewarded-ad-unit-ID"];
        isFirstLoad = YES;
      }
      
      - (void)loadAd
      {
        // If first load - load ad from Amazon's SDK, then load ad for MAX
        if ( isFirstLoad )
        {
          isFirstLoad = NO;
      
          DTBAdLoader *adLoader = [[DTBAdLoader alloc] init];
      
          // Switch video player width and height values(320, 480) depending on device orientation
          [adLoader setAdSizes: @[
            [[DTBAdSize alloc] initVideoAdSizeWithPlayerWidth: 320 height: 480 andSlotUUID:@"Amazon-video-rewarded-slot-ID"]
          ]];
          [adLoader loadAd: self];
        }
        else
        {
          [rewardedAd loadAd];
        }
      }
      
      - (void)onSuccess:(DTBAdResponse *)adResponse
      {
        // 'rewardedAd' is your instance of MARewardedAd
        [rewardedAd setLocalExtraParameterForKey: @"amazon_ad_response" value: adResponse];
        [rewardedAd loadAd];
      }
      
      - (void)onFailure:(DTBAdError)error dtbAdErrorInfo:(DTBAdErrorInfo *)errorInfo
      {
        // 'rewardedAd' is your instance of MARewardedAd
        [rewardedAd setLocalExtraParameterForKey: @"amazon_ad_error" value: errorInfo];
        [rewardedAd loadAd];
      }
      
      @end
    • import AppLovinSDK
      import DTBiOSSDK
      
      class ExampleViewController: UIViewController
      {
        private static var rewardedAd = MARewardedAd.shared(withAdUnitIdentifier: "MAX-rewarded-ad-unit-ID")
        private static var isFirstLoad = true
        func loadAd()
        {
          // If first load - load ad from Amazon's SDK, then load ad for MAX
          if Self.isFirstLoad
          {
            Self.isFirstLoad = false
      
            let adLoader = DTBAdLoader()
      
            // Switch video player width and height values(320, 480) depending on device orientation
            adLoader.setAdSizes([DTBAdSize(videoAdSizeWithPlayerWidth: 320, height: 480, andSlotUUID: "Amazon-video-rewarded-slot-ID")!])
            adLoader.loadAd(self)
          }
          else
          {
            Self.rewardedAd.load()
          }
        }
      }
      
      extension ExampleViewController: DTBAdCallback
      {
        func onSuccess(_ adResponse: DTBAdResponse!)
        {
          // 'rewardedAd' is your instance of MARewardedAd
          Self.rewardedAd.setLocalExtraParameterForKey("amazon_ad_response", value: adResponse)
          Self.rewardedAd.load()
        }
      
        func onFailure(_ error: DTBAdError, dtbAdErrorInfo: DTBAdErrorInfo!)
        {
          // 'rewardedAd' is your instance of MARewardedAd
          Self.rewardedAd.setLocalExtraParameterForKey("amazon_ad_error", value: dtbAdErrorInfo)
          Self.rewardedAd.load()
        }
      }

    Testing Amazon Publisher Services

    AppLovin recommends that you enable test mode for Amazon’s SDK to receive test ads. You can do this with the following calls:

    • [[DTBAds sharedInstance] setLogLevel: DTBLogLevelAll];
      [[DTBAds sharedInstance] setTestMode: YES];
    • DTBAds.sharedInstance().setLogLevel(DTBLogLevelAll)
      DTBAds.sharedInstance().testMode = true

    To filter your waterfalls to contain only Amazon ads, navigate to Select Live Network in the Mediation Debugger and select the Amazon network.

    Enable Google Ad Manager

    In your app’s Info.plist, add a GADIsAdManagerApp key with the Boolean value of YES.

    GADIsAdManagerApp (Boolean): YES

    Disable App Transport Security

    Disable App Transport Security (ATS) by adding NSAppTransportSecurity to your app’s Info.plist. Then add the key NSAllowsArbitraryLoads and set it to YES. Make sure this is the only key present.

    App Transport Security Settings (Dictionary): 1 item. Allow Arbitrary Loads (Boolean): YES.

    SKAdNetwork

    Refer to the SKAdNetwork documentation for integration instructions.

    Install the New Pods

    Run the following on the command line:

    pod install --repo-update