Building a Custom Adapter

  • Updated

You can write a custom adapter if you want to support an ad network that is not listed in the AppLovin MAX Mediation Matrix.

  • Getting Started

    Implement a subclass of com.applovin.mediation.adapters.MediationAdapterBase. This subclass enables the interface between your mediation adapter and the AppLovin MAX SDK. That interface handles various functions of your SDK, including initialization, versioning, and resource cleanup.

    1. Create a subclass of MediationAdapterBase in the com.applovin.mediation.adapters package of your application. The name of this class should contain the network name (for example, com.mycompanyname.MyNetworkMediationAdapter).
    2. Override the initialize(final MaxAdapterInitializationParameters parameters, final Activity activity, final OnCompletionListener onCompletionListener) method and implement code that initializes your ad network SDK. If you need to access the app ID set in the UI, you can do so by means of parameters.getServerParameters().getString( "app_id", null );. This logic executes in parallel with the initialization of the AppLovin SDK. Call onCompletionListener.onCompletion() after you initialize the ad network, and pass that completion handler one of the following values:
      • While the ad network SDK is initializing: InitializationStatus.INITIALIZING
      • If the ad network SDK initializes successfully: InitializationStatus.INITIALIZED_SUCCESS
      • If the ad network SDK fails to initialize: InitializationStatus.INITIALIZED_FAILURE (with a relevant error message)
      • If the ad network SDK does not have an initialization callback status: InitializationStatus.DOES_NOT_APPLY
      • If the ad network explicitly initialized, but without a status: InitializationStatus.INITIALIZED_UNKNOWN
    3. Override the getSdkVersion() method and implement code that returns the network SDK version string from that method.
    4. Override the getAdapterVersion() method and implement code that returns the version number of the mediation adapter from that method. All of AppLovin’s adapters use a five-number versioning scheme: The leftmost four numbers correspond to the network SDK version and the last number denotes the minor version number which refers to the adapter release.
    5. Override the onDestroy() method and implement the clean-up logic for the network SDK objects in that method.

    Banner Ads

    1. Implement the MaxAdViewAdapter interface in your com.mycompanyname.MyNetworkMediationAdapter class.
    2. Override the loadAdViewAd() method which requests an ad. Call the parameters.getThirdPartyAdPlacementId() method to get the placement ID you need for your ad logic.
    3. Call the appropriate MaxAdViewAdapterListener methods to notify the AppLovin MAX SDK about banner lifecycle events:
      • When an ad loads successfully, call MaxAdViewAdapterListener.onAdViewAdLoaded().
      • When an ad load fails, call MaxAdViewAdapterListener.onAdViewAdLoadFailed() with an appropriate MaxAdapterError.
      • Optionally, make the following banner lifecycle events notification calls as appropriate: onAdViewAdClicked(), onAdViewAdCollapsed(), onAdViewAdDisplayed(), onAdViewAdDisplayFailed(), onAdViewAdExpanded(), onAdViewAdHidden().

    Interstitials

    1. Implement the MaxInterstitialAdapter interface in your com.mycompanyname.MyNetworkMediationAdapter class.
    2. Override the loadInterstitialAd() method which requests an ad. Call the parameters.getThirdPartyAdPlacementId() method to get the placement ID you need for your ad logic.
    3. Override the showInterstitialAd() method which shows the loaded ad. Call the parameters.getThirdPartyAdPlacementId() method to get the placement ID you need for your ad logic. If the ad is not ready, call MaxInterstitialAdapterListener.onInterstitialAdDisplayFailed( MaxAdapterError.AD_NOT_READY ).
    4. Call the appropriate MaxInterstitialAdapterListener methods to notify the AppLovin MAX SDK about interstitial lifecycle events:
      • When an ad loads successfully, call MaxInterstitialAdapterListener.onInterstitialAdLoaded().
      • When an ad load fails, call MaxInterstitialAdapterListener.onInterstitialAdLoadFailed() with an appropriate MaxAdapterError.
      • When an ad is hidden, call MaxInterstitialAdapterListener.onInterstitialAdHidden().
      • Optionally, make the following interstitial lifecycle events notification calls as appropriate: onInterstitialAdClicked(), onInterstitialAdDisplayFailed().

    Rewarded Ads

    1. Implement the MaxRewardedAdapter interface in your com.mycompanyname.MyNetworkMediationAdapter class.
    2. Override the loadRewardedAd() method which requests an ad. Call the parameters.getThirdPartyAdPlacementId() method to get the placement ID you need for your ad logic.
    3. Override the showRewardedAd() method which shows the loaded ad. Call the parameters.getThirdPartyAdPlacementId() method to get the placement ID you need for your ad logic. If the ad is not ready, call MaxRewardedAdapterListener.onRewardedAdDisplayFailed( MaxAdapterError.AD_NOT_READY ).
    4. Call the appropriate MaxRewardedAdapterListener methods to notify the AppLovin MAX SDK about rewarded video lifecycle events:
      • When an ad loads successfully, call MaxRewardedAdapterListener.onRewardedAdLoaded().
      • When an ad load fails, call MaxRewardedAdapterListener.onRewardedAdLoadFailed() with an appropriate MaxAdapterError.
      • When an ad starts playing, call MaxRewardedAdapterListener.onRewardedAdDisplayed().
      • If a reward should be presented to the user, call MaxRewardedAdapterListener.onUserRewarded() with an appropriate MaxReward amount and currency. If no amount is available, default to MaxReward.DEFAULT_AMOUNT. AppLovin recommends that you call this immediately before MaxRewardedAdapterListener.onRewardedAdHidden().
      • When an ad is hidden, call MaxRewardedAdapterListener.onRewardedAdHidden().
      • Optionally, make the following rewarded video lifecycle event notification call as appropriate: onRewardedAdClicked().

    Native Ads

    1. Implement the MaxNativeAdapter interface in your com.mycompanyname.MyNetworkMediationAdapter class.
    2. Override the loadNativeAd() method which requests an ad.
    3. Call the appropriate MaxNativeAdapterListener methods to notify the AppLovin MAX SDK about native ad lifecycle events:
      • When an ad loads successfully, call MaxNativeAdapterListener.onNativeAdLoaded().
      • When an ad load fails, call MaxNativeAdapterListener.onNativeAdLoadFailed() with an appropriate MaxAdapterError.
      • When an ad displays, call MaxNativeAdapterListener.onNativeAdDisplayed().
      • When the user clicks on an ad, call MaxNativeAdapterListener.onNativeAdClicked().

    Privacy

    MAX offers three boolean flags represented by a Boolean object that indicates whether the user provides privacy consent (or that are null if the user has indicated neither consent or no consent). To obtain the value of these flags, use the following methods of the parameters object passed into each method:

    MaxAdapterParameters.hasUserConsent()
    for the GDPR consent flag. You can find out about how to determine if GDPR applies to the user in the Privacy page of this documentation.
    MaxAdapterParameters.isDoNotSell()
    for the multi-state targeted advertising consent flag. AppLovin currently does not have an API to indicate whether the user belongs in a region to which this applies.
    MaxAdapterParameters.isAgeRestrictedUser()
    for the COPPA flag
  • Getting Started

    Implement a subclass of ALMediationAdapter. This subclass enables the interface between your mediation adapter and the AppLovin MAX SDK. That interface handles various functions of your SDK, including initialization, versioning, and resource cleanup.

    1. Create a .m and .h extending from ALMediationAdapter in your project. The name of this class should contain the network name (for example, MyNetworkMediationAdapter).
    2. Implement the - (void)initializeWithParameters:(id<MAAdapterInitializationParameters>)parameters completionHandler:(void (^)(MAAdapterInitializationStatus NSString *_Nullable))completionHandler method and implement code that initializes your ad network SDK. If you need to access the app ID set in the UI, you can do so by means of parameters.serverParameters[@"app_id"]. This logic executes in parallel with the initialization of the AppLovin SDK. Call completionHandler after you initialize the ad network, and pass that handler one of the following values:
      • While the ad network SDK is initializing: MAAdapterInitializationStatusInitializing
      • If the ad network SDK initializes successfully: MAAdapterInitializationStatusInitializedSuccess
      • If the ad network SDK fails to initialize: MAAdapterInitializationStatusInitializedFailure (with a relevant error message)
      • If the ad network SDK does not have an initialization callback status: MAAdapterInitializationStatusDoesNotApply (with null as the error message)
      • If the ad network explicitly initialized, but without a status: MAAdapterInitializationStatusInitializedUnknown
    3. Implement the - (NSString *)SDKVersion method and implement code that returns the network SDK version string from that method.
    4. Implement the - (NSString *)adapterVersion method and implement code that returns the version number of the mediation adapter from that method. All of AppLovin’s adapters use a five-number versioning scheme: The leftmost four numbers correspond to the network SDK version and the last number denotes the minor version number which refers to the adapter release.
    5. Implement the - (void)destroy method and implement the clean-up logic for the network SDK objects in that method.

    Banner Ads

    1. Implement the MAAdViewAdapter protocol in your MyNetworkMediationAdapter class.
    2. Implement the - (void)loadAdViewAdForParameters:(id<MAAdapterResponseParameters>)parameters adFormat:(MAAdFormat *)adFormat andNotify:(id<MAAdViewAdapterDelegate>)delegate method which requests an ad. Call the parameters.thirdPartyAdPlacementIdentifier method to get the Placement ID you need for your ad logic.
    3. Call the appropriate MAAdViewAdapterDelegate methods to notify the AppLovin MAX SDK about banner lifecycle events:
      • When an ad loads successfully, call -[MAAdViewAdapterDelegate didLoadAdForAdView].
      • When an ad load fails, call -[MAAdViewAdapterDelegate didFailToLoadAdViewAdWithError:] with an appropriate MAAdapterError.
      • Optionally, make the following banner lifecycle event notification calls as appropriate: didClickAdViewAd, didCollapseAdViewAd, didDisplayAdViewAd, didExpandAdViewAd, didFailToDisplayAdViewAdWithError, didHideAdViewAd.

    Interstitials

    1. Implement the MAInterstitialAdapter protocol in your MyNetworkMediationAdapter class.
    2. Declare the - (void)loadInterstitialAdForParameters:(id<MAAdapterResponseParameters>)parameters andNotify:(id<MAInterstitialAdapterDelegate>)delegate method which requests an ad. Call the parameters.thirdPartyAdPlacementIdentifier method to get the placement ID you need for your ad logic.
    3. Declare the - (void)showInterstitialAdForParameters:(id<MAAdapterResponseParameters>)parameters andNotify:(id<MAInterstitialAdapterDelegate>)delegate method which shows the loaded ad. Call the parameters.thirdPartyAdPlacementIdentifier method to get the placement ID you need for your ad logic. If the ad is not ready, call -[MAInterstitialAdapterDelegate didFailToDisplayInterstitialAdWithError: MAAdapterError.adNotReady].
    4. Call the appropriate MAInterstitialAdapterDelegate methods to notify the AppLovin MAX SDK about interstitial lifecycle events:
      • When an ad loads successfully, call -[MAInterstitialAdapterDelegate didLoadInterstitialAd:].
      • When an ad load fails, call -[MAInterstitialAdapterDelegate didFailToLoadInterstitialAdWithError:] with an appropriate MAAdapterError.
      • When an ad displays successfully, call -[MAInterstitialAdapterDelegate didDisplayInterstitialAd].
      • When an ad is hidden, call -[MAInterstitialAdapterDelegate didHideInterstitialAd:].
      • Optionally, make the following interstitial lifecycle event notification calls as appropriate: didClickInterstitialAd, didFailToDisplayInterstitialAdWithError.

    Rewarded Ads

    1. Implement the MARewardedAdapter protocol in your MyNetworkMediationAdapter class.
    2. Declare the - (void)loadRewardedAdForParameters:(id<MAAdapterResponseParameters>)parameters andNotify:(id<MARewardedAdapterDelegate>)delegate; method which requests an ad. Call the parameters.thirdPartyAdPlacementIdentifier method to get the placement ID you need for your ad logic.
    3. Declare the - (void)showRewardedAdForParameters:(id<MAAdapterResponseParameters>)parameters andNotify:(id<MARewardedAdapterDelegate>)delegate; method which shows the loaded ad. Call the parameters.thirdPartyAdPlacementIdentifier method to get the placement ID you need for your ad logic. If the ad is not ready, call -[MARewardedAdapterDelegate didFailToDisplayRewardedAdWithError: MAAdapterError.adNotReady].
    4. Call the appropriate MARewardedAdapterDelegate methods to notify the AppLovin MAX SDK about rewarded video lifecycle events:
      • When an ad loads successfully, call -[MARewardedAdapterDelegate didLoadRewardedAd:].
      • When an ad load fails, call -[MARewardedAdapterDelegate didFailToLoadRewardedAdWithError:] with an appropriate MAAdapterError.
      • When an ad starts playing, call -[MARewardedAdapterDelegate didDisplayRewardedAd:].
      • If a reward should be presented to the user, call -[MARewardedAdapterDelegate didRewardUserWithReward:] with an appropriate MAReward amount and currency. If no amount is available, default to MAReward.defaultAmount. AppLovin recommends that you call this immediately before -[MARewardedAdapterDelegate didHideRewardedAd:].
      • When an ad is hidden, call -[MARewardedAdapterDelegate didHideRewardedAd:].
      • Optionally, make the following rewarded video lifecycle event notification call as appropriate: didClickRewardedInterstitialAd.

    Native Ads

    1. Implement the MANativeAdAdapter protocol in your MyNetworkMediationAdapter class.
    2. Implement the - (void)loadNativeAdForParameters:(id<MAAdapterResponseParameters>)parameters andNotify:(id<MANativeAdAdapterDelegate>)delegate; method which requests an ad.
    3. Call the appropriate MANativeAdAdapterDelegate methods to notify the AppLovin MAX SDK about native ad lifecycle events:
      • When an ad loads successfully, call -[MANativeAdAdapterDelegate didLoadAdForNativeAd:].
      • When an ad load fails, call -[MANativeAdAdapterDelegate didFailToLoadNativeAdWithError:] with an appropriate MAAdapterError.
      • When an ad displays, call -[MANativeAdAdapterDelegate didDisplayNativeAdWithExtraInfo:].
      • When the user clicks on an ad, call -[MANativeAdAdapterDelegate didClickNativeAd:].

    Privacy

    MAX offers three boolean flags represented by an NSNumber object that indicates whether the user provides privacy consent (or that are nil if the user has indicated neither consent or no consent). To obtain the value of these flags, use the following APIs of the parameters object passed into each method:

    -[MAAdapterParameters hasUserConsent]
    for the GDPR consent flag. You can find out how to determine if GDPR applies to the user in the Privacy page of this documentation.
    -[MAAdapterParameters isDoNotSell]
    for the multi-state targeted advertising consent flag. AppLovin currently does not have an API to indicate whether the user belongs in the relevant region.
    -[MAAdapterParameters isAgeRestrictedUser]
    for the COPPA flag

Testing

You can test your custom adapter by using the MAX Demo App and Mediation Debugger. To get an ad request easily, you can set the CPM of your placement in the waterfall higher.

Troubleshooting

If your custom adapter does not appear to be included in the waterfall as you expect, use the following checklist to fix the most common issues that might be causing this:

  1. Disable Test Mode.
  2. Make sure that the app package name, ad unit, and SDK key all match.
  3. Test with a physical device.
  4. Set the CPM of the custom network high enough that it has a high chance of winning in the waterfall.