Adapter Guidelines for Supported Networks

Working Agreement

Networks own the adapter code and are responsible for any changes necessary 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 Availability Requirements

  • Android SDK on JCenter
  • iOS SDK on CocoaPods

Core Adapter Requirements

  • Pre-initialization of the network SDK should be supported. You must 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 the steps below:
  • Publisher data management: If your network SDK supports targeting, publishers can pass the data using the following approaches.
  • Implement MoPub Logging - Network SDKs are responsible for implementing MoPub’s logging API in the adapters to maintain consistency with MoPub, as well as other mediation SDKs. When the logging API is used, you will have access to expressive and constructive logs that help all customers with debugging purposes.

    Additional Tip:

    • 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 that networks need to support:
    • Initialization completion callback
    • Ad load success callback
    • Ad load failure callback
    • Impression callback
    • Click callback
  • APIs that should be implemented by format

  • Network SDKs are responsible for ensuring no memory leaks, crashes, or negative performance issues manifest during the lifecycle of the adapters.
  • Consume MoPub’s canCollectPersonalData - MoPub will be obtaining consent on behalf of supported mediation partners. We will share the user consent via adapters

  • LegitimateInterest - MoPub SDK version 5.5.0+ allows supported mediated networks and publishers to opt-in to process a user’s personal data based on legitimate interest basis when GDPR applies and when the user consent value is unknown.

More details are available here

Latency optimization requirements

Any possible timeouts for ad responses should be identified and addressed in the adapters to avoid high ad latency.

Code Style Guidelines

Android (Java)

Class Layout

Classes should be laid out in the following order:

  • Package declaration, followed by a new line
    package com.mopub.mobileads;
    
  • Import statements. These should be grouped by top-level package. Each top-level package is separated by a newline. You can use Android Studio’s Optimize Imports. No import statements should end with an asterisk *

  • Class or interface declaration: ClassNames are written in UpperCamelCase.
    // imports
    public class MyAdapterConfiguration extends BaseAdapterConfiguration {
    }
    

Access Modifiers

  • They should appear in the order recommended by the Java Language Specification:
    public protected private abstract default static final transient volatile synchronized native strictfp
    
  • Check that local variables that never have their values changed are declared final

Variable names

  • Static variable declarations and initializer blocks, and final variables must come before non-final ones. final static fields should be all caps separated by underscores.
    private static final String TEST_ID_KEY = "testId";
    
  • Non-final static fields should follow the sVarname convention. When possible, group identical modifiers together (i.e. private static Strings should be grouped together).
    public static String sTestString;
    public static String sKey;
    
  • Non-static member variable declarations, and final variables must come before non-final ones. Non-public variables must 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

  • Method names are written in lowerCamelCase. Put getters and setters before any other methods, keeping the setter and getter for each field together.
    Example: getAdapterName(), setName()
    
  • @override annotation is used whenever necessary, basically used when implementing an interface method.

Formatting

  • Braces: used whenever necessary. If and else statements must always have braces 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 should be used.
  • Comments: we encourage to use block style comments /** ---- */

  • Whitespaces:
    • Remove trailing whitespaces before committing.
    • Use 4 spaces to indent and do not use tab character
    • A line may not exceed 120 characters.
    • When concatenating strings, break after the + operator.
    • Exactly one blank line separates each section that is present

iOS (Objective-C)

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 Jump box.
  • Properties: Do not specify strong 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, isReady(), isInitialized().

Variable Names

Variables should be 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. 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

  • Braces: used whenever necessary. 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;
  • If and else statements must always have braces even if there is a single line in the block
  • Use 4 spaces to indent and 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 that is present

Commit Messages

  • This should be a short summary of your commit.
  • Your first line should start with a verb in the imperative.
  • You can have subsequent lines which give further detail about the commit.

Last updated December 23, 2019

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.)