Adapter Guidelines for Supported Networks

Working Agreement

Networks own the adapter code and are responsible for any changes required for ongoing network SDK releases. MoPub will own changes if the SDK <-> Adapter protocol changes as part of a MoPub SDK release. MoPub is responsible for ongoing adapter certifications and adapter releases. MoPub hosts the adapters on MoPub-owned mediation GitHub repositories for Android, iOS, and Unity.

Network SDK Requirements

  • Android SDK on JCenter
  • iOS SDK on CocoaPods

Core Adapter Requirements

  • Pre-initialization: Support pre-initialization of the network SDK. Implement an AdapterConfiguration class to provide an interface between your network SDK and the MoPub SDK. This interface facilitates a pre-initialization of your SDK, and can be written using these instructions for Android and iOS.

  • Publisher data management: If your network SDK supports targeting, publishers can pass the data using these approaches for Android and iOS.

  • MoPub logging: Network SDKs are responsible for implementing MoPub’s logging API in the adapters to maintain consistency with MoPub, and other mediation SDKs. When you use the logging API, you will have access to expressive and constructive logs for debugging purposes. Refer to these instructions for Android and iOS.

    Additional logging tips:

    • Always use MoPubLog to log adapter events and always log them right before the listener callbacks
    • Log all the ad lifecycle events (ad load, ad show, ad clicked, ad closed)
    • Read the log level that is set from the MoPub SDK, and find the closest level provided by your mediation SDK
  • Required callbacks: Networds must support the following callbacks:

    • Initialization completion callback
    • Ad load success callback
    • Ad load failure callback
    • Impression callback
    • Click callback
  • APIs for formats: Implement the required APIs for each ad format you support:

  • Network SDKs are responsible for ensuring that no memory leaks, crashes, or negative performance issues manifest during the lifecycle of the adapters.

GDPR and Latency Requirements

  • GDPR: If you are using MoPub’s consent model, email mopub-mediation@twitter.com for more information about collecting GDPR consent status.

  • Latency optimization: Identify and address any possible timeouts for ad responses in the adapters to avoid high ad latency.

Android (Java) Code Style Guidelines

Class Layout

Organize classes in the following order:

  • Package declaration, followed by a new line:

     package com.mopub.mobileads;
    
  • Group import statements by top-level package. Each top-level package is separated by a newline. You can use Android Studio’s Optimize Imports. Do not end import statements with an asterisk *.

  • In class or interface declarations, ClassNames are written in UpperCamelCase.

     // imports
     public class MyAdapterConfiguration extends BaseAdapterConfiguration {
     }
    

Access Modifiers

  • Place access modifiers in the order recommended by the Java Language Specification:

     public protected private abstract default static final transient volatile synchronized native strictfp
    
  • Declare local variables that never have their values changed final

Variable Names

  • Place static variable declarations and initializer blocks, as well as final variables, before non-final ones. Write final static fields in all caps, separated by underscores.

     private static final String TEST_ID_KEY = "testId";
    
  • For non-final static fields, follow the sVarname convention. When possible, group identical modifiers together (that is, group private static Strings together).

     public static String sTestString;
     public static String sKey;
    
  • Place non-static member variable declarations and final variables before non-final ones.

  • For non-public variables, follow the mVarname convention. When possible, group identical modifiers together.

       public class MyAdapterConfiguration extends BaseAdapterConfiguration {
         public final int intVar;
         private final int mIntVar;
      
         protected String mProtectedString;
         private String mString;
         String mVariable;
     }
    

Methods

  • Write method names in lowerCamelCase.

  • Put getters and setters before any other methods, keeping the setter and getter for each field together:

     Example: getAdapterName(), setName()
    
  • Use the @override annotation whenever necessary, generally when implementing an interface method.

Formatting

  • Use braces whenever necessary. Always use braces for if and else statements, even if there is a single line in the block.

    • No line break before the opening brace
    • Line break after the opening brace
    • Line break before the closing brace
  • Check style:

    • Check no ‘tab’ characters in the source code
    • No two consecutive empty lines
  • Use block style comments, as in /** ---- */

  • Whitespaces:

    • Remove trailing whitespaces before committing
    • Use four spaces to indent; do not use the ‘tab’ character
    • A line may not exceed 120 characters
    • When concatenating strings, break after the + operator
    • Exactly one blank line separates each section

iOS (Objective-C) Code Style Guideliens

Class Layout

Organize import statements by adding framework headers first then local headers in alphabetical order.

  • Import iOS modules using @import after #import. This forces each .h in each #import to perform its own module imports first.

  • Minimize imports in .h files. Import only what is absolutely necessary in your header files and import the necessary headers in your implementation (.m) file instead.

Methods

  • Use #pragma mark to segregate class overrides. You may want to find methods quickly through the category from the Jump box.

  • For properties, co not specify strong attributes or assign attributes for properties. They are default attributes.

     @property (nonatomic) BOOL isValid;   // => assign by default
     @property (nonatomic) NSString *name; // => strong by default
    
  • Use camelCase for method names

  • Use descriptive names for methods and arguments; for example, start with a verb, as in isReady() or isInitialized()

Variable Names

Make variable names long enough to indicate what they are and how they relate to the code around them.

  • Use static const and k prefix for private constants, and name constants with camel case after k:

     static NSString * const kTestId  = @"TestId";
    
  • Name private iVars with a _ prefix

  • Name global and static variables with a prefix; for example, s_, s or g:

     static MyExampleClass *sMyclass = nil;
       
     @implementation MyExampleClass
     + (instancetype)sharedInstance
     {
         return sMyclass;
     }
     @end
    

Formatting

  • Use braces whenever necessary, and add opening brace on a new line.
  • Place a space after the type name for pointers, but not before the variable name; for example:

     Foo *foo = [[Foo alloc] init];
     - (Bunch *)bunchWithBerries(NSArray *)berries;
    
  • Always use braces for if and else statements, even if there is a single line in the block.
  • Use four spaces to indent; do not use ‘tab’ character.
  • Split long lines into multi-line code for better readability.
  • A line may not exceed 120 characters.
  • When concatenating strings, break after the + operator.
  • Exactly one blank line separates each section.

Commit Messages

  • Make this a short summary of your commit.
  • Start your first line with a verb in the imperative.
  • You can add subsequent lines that provide further detail about the commit.

Last updated November 18, 2020

TWITTER, MOPUB, and the Bird logo are trademarks of Twitter, Inc. or its affiliates. All third party logos and trademarks included are the property of their respective owners.

© 2020 MoPub (a division of Twitter, Inc.)