Mediation

Creating a Module

Core SDK Dependency 🔗

All modules in the Chartboost ecosystem must depend upon the Core SDK. This is to ensure that the module you develop can be initialized by the Core SDK. Include the following dependency to your module:

"com.chartboost.core": "1.0.2”

Required Module API Implementations 🔗

Module 🔗

The module’s initialization entry point must conform to the Module interface so that the module is initializable by the Core SDK.

Your module implementation should gracefully handle situations where multiple initialization attempts are made. If your module is a single initialization type of implementation, it is recommended to synchronize your initialization method to prevent multithreaded access and to maintain an initialization state.

The interfaces are listed in the example below, however, we recommended that you double check the Core SDK API Reference.

public abstract class Module
{
    /// Invoked when this Module instanced has successfully initialized.
    public event Action ModuleReady;
    
    /// The module identifier.
    public abstract string ModuleId { get; }

    /// The version of the module.
    public abstract string ModuleVersion { get; }

    /// The designated initializer for the module. Sets up the module to make it ready to be used.
    /// <param name="configuration"></param>
    /// <returns> An error should be passed if the initialization failed, whereas null should be passed if it succeeded.</returns>
    protected abstract Task<ChartboostCoreError?> Initialize(ModuleConfiguration configuration);

    /// <summary>
    /// Updates the <see cref="Module"/> with JSON data from the server. A publisher is recommended to
    /// initialize via the constructor with module-specific parameters rather than using this function.
    /// When creating a module, please make sure it's possible to send a <see cref="IReadOnlyDictionary{TKey,TValue}"/> credentials
    /// object to set up the parameters of this module.
    /// <br/>
    /// <br/>
    /// Note: Modules should not perform costly operations on this initializer.
    /// <see cref="ChartboostCore"/> SDK may instantiate and discard several instances of the same module.
    /// <see cref="ChartboostCore"/> SDK keeps strong references to modules that are successfully initialized.
    /// </summary>
    /// <param name="credentials">A <see cref="IReadOnlyDictionary{TKey,TValue}"/> containing all the information required to initialize
    /// this module, as defined on the Chartboost Core's dashboard.</param>
    protected virtual void UpdateCredentials(IReadOnlyDictionary<string, object> credentials)
        => LogController.Log($"Updating Credentials for Module: {ModuleId} with Credentials", LogLevel.Debug);
}

Using Environment Information 🔗

The ChartboostCore public API provides three predefined environment information objects for different purposes:

  • AdvertisingEnvironment
  • AnalyticsEnvironment
  • AttributionEnvironment

These environments provide information based upon an intended purpose and are grouped to provide module creators guidance on what information is permissible for a given purpose. These environments are static, and can be accessed before the Core SDK is initialized.

The environment properties located in the ChartboostCore class are listed below.

/// <summary>
    /// An environment that contains information intended solely for analytics purposes.
    /// </summary>
    public interface IAnalyticsEnvironment : IAttributionEnvironment, IAdvertisingEnvironment
    {
        /// <summary>
        /// The current network connection type, e.g. wifi.
        /// </summary>
        NetworkConnectionType NetworkConnectionType { get; }
        
        /// <summary>
        /// The device volume level.
        /// </summary>
        double? Volume { get; }
        
        /// <summary>
        /// The system identifier for vendor (IFV).
        /// </summary>
        Task<string?> VendorIdentifier { get; }
        
        /// <summary>
        /// The scope of the identifier for vendor.
        /// </summary>
        Task<VendorIdentifierScope> VendorIdentifierScope { get; }
        
        /// <summary>
        /// The tracking authorization status, as determined by the system’s AppTrackingTransparency framework.
        /// Requires iOS 14.0+.
        /// Only supported in iOS devices, other platforms default to Unsupported.
        /// </summary>
        AuthorizationStatus AppTrackingTransparencyStatus { get; }
        
        /// <summary>
        /// The version of the app.
        /// </summary>
        string? AppVersion { get; }
        
        /// <summary>
        /// The session duration, or 0 if the <see cref="ChartboostCore.Initialize"/> method has not been called yet.
        /// A session starts the moment <see cref="ChartboostCore.Initialize"/> is called for the first time, or when the user consent status changes from
        /// <see cref="Chartboost.Core.Consent.ConsentStatus.Granted"/> to any other status.
        /// </summary>
        double AppSessionDuration { get; }
        
        /// <summary>
        /// The session identifier, or null if the <see cref="ChartboostCore.Initialize"/> method has not been called yet.
        /// A session starts the moment <see cref="ChartboostCore.Initialize"/> is called for the first time, or when the user consent status changes from
        /// <see cref="Chartboost.Core.Consent.ConsentStatus.Granted"/> to any other status.
        /// </summary>
        string? AppSessionIdentifier { get; }
        
        /// <summary>
        /// Indicates whether the user is underage.
        /// This is determined by the latest value set by the publisher through a call to <see cref="IPublisherMetadata.SetIsUserUnderage"/>, as well as by the “child-directed” option defined on the Chartboost Core dashboard.
        /// The more restrictive option is used.
        /// </summary>
        bool? IsUserUnderage { get; }

        /// <summary>
        /// The publisher-defined session identifier set by the publisher through a call to <see cref="IPublisherMetadata.SetPublisherSessionIdentifier"/>.
        /// </summary>
        string? PublisherSessionIdentifier { get; }
        
        /// <summary>
        /// The publisher-defined application identifier set by the publisher through a call to <see cref="IPublisherMetadata.SetPublisherAppIdentifier"/>.
        /// </summary>
        string? PublisherAppIdentifier { get; }
        
        /// <summary>
        /// The framework name set by the publisher through a call to <see cref="IPublisherMetadata.SetFramework"/>.
        /// </summary>
        string? FrameworkName { get; }
        
        /// <summary>
        /// The framework version set by the publisher through a call to <see cref="IPublisherMetadata.SetFramework"/>.
        /// </summary>
        string? FrameworkVersion { get; }
        
        /// <summary>
        /// The player identifier set by the publisher through a call to <see cref="IPublisherMetadata.SetPlayerIdentifier"/>.
        /// </summary>
        string? PlayerIdentifier { get; }
        
        /// <summary>
        /// The system advertising identifier (IFA).
        /// </summary>
        new Task<string?> AdvertisingIdentifier { get; }
        
        event Action IsUserUnderageChanged;
        event Action PublisherSessionIdentifierChanged;
        event Action PublisherAppIdentifierChanged;
        event Action FrameworkNameChanged;
        event Action FrameworkVersionChanged;
        event Action PlayerIdentifierChanged;
    }




/// <summary>
/// An environment that contains information intended solely for advertising purposes.
/// </summary>
public interface IAdvertisingEnvironment
{
    /// <summary>
    /// The OS name, e.g. “iOS” or “iPadOS”.
    /// </summary>
    string OSName { get; }
    
    /// <summary>
    /// The OS version, e.g. “17.0”.
    /// </summary>
    string OSVersion { get; }
    
    /// <summary>
    /// The device make, e.g. “Apple”.
    /// </summary>
    string DeviceMake { get; }
    
    /// <summary>
    /// The device model, e.g. “iPhone11,2”.
    /// </summary>
    string DeviceModel { get; }
    
    /// <summary>
    /// The device locale string, e.g. “en-US”.
    /// </summary>
    string? DeviceLocale { get; }
    
    /// <summary>
    /// The height of the screen in pixels.
    /// </summary>
    double? ScreenHeightPixels { get; }
    
    /// <summary>
    /// The screen scale.
    /// </summary>
    double? ScreenScale { get; }
    
    /// <summary>
    /// The width of the screen in pixels.
    /// </summary>
    double? ScreenWidthPixels { get; }
    
    /// <summary>
    /// The app bundle identifier.
    /// </summary>
    string? BundleIdentifier { get; }
    
    /// <summary>
    /// Indicates whether the user has limited ad tracking enabled.
    /// </summary>
    Task<bool?> LimitAdTrackingEnabled { get; }
    
    /// <summary>
    /// The system advertising identifier (IFA).
    /// </summary>
    Task<string?> AdvertisingIdentifier { get; }
}


/// <summary>
/// An environment that contains information intended solely for attribution purposes.
/// </summary>
public interface IAttributionEnvironment
{
    /// <summary>
    /// The system advertising identifier (IFA).
    /// </summary>
    Task<string?> AdvertisingIdentifier { get; }
    
    /// <summary>
    /// The device user agent.
    /// </summary>
    Task<string?> UserAgent { get; }
}

Subscribing to Publisher Metadata Updates 🔗

Publisher metadata can be set or updated by the Publisher at any point in the app’s lifecycle. If your module requires reacting to changes in these values in real time, you can subscribe to these changes by calling the AnalyticsEnvironment.addObserver() method with your EnvironmentObserver object.

Modules do not need to handle their own user consent collection, and can instead rely upon the Core SDK’s consent mediation to provide that information.

To query the consent values from the currently initialized CMP, access the ConsentManagementPlatform interface from the ChartboostCore.consent property.

Consent information is valid only if a CMP adapter was successfully initialized by the Core SDK.

In the event that no CMP adapter was successfully initialized, the current consent information will be unavailable, and modules should assume that consent has not been given.

Handling Underage Users 🔗

CMPs do not provide COPPA related or child-directed APIs as COPPA relates to whether a user is underage or an app is child-directed, not whether the user has given consent for various use cases.

This information is captured by the isUserUnderage property in AnalyticsEnvironment, and is set by the Publisher via PublisherMetadata.setIsUserUnderage().

To obtain the consent, query the ConsentManagementPlatform.consents property for the map of current consent states.

You can then use one of the following keys in the table below to access the desired consent value if it exists. Each platform will have its own convenience constants as well.

Note that if a consent value does not exist for the specified key, it likely means that the CMP does not support that consent standard.

Consent Standard Key Description
ccpa_opt_in CCPA opt-in
gdpr_consent_given GDPR consent
IABGPP_HDR_GppString IAB GPP string
IABTCF_TCString IAB TCF string
IABUSPrivacy_String IAB USP string

Consent may change at any given time, and it is recommended to subscribe to consent changes if your module needs to react in real time to those consent changes.

To subscribe to consent changes, register your observer using the ConsentManagementPlatform.addObserver() call.

The Core SDK also provides a 500ms debouncing logic for CMP consent changes so that observers are not inundated with callbacks in a short period of time.

Usage Example 🔗

// Querying TCF, USP, GPP strings from ChartboostCore.consent.
var consents = ChartboostCore.Consent.Consents;
var tcfString = consents[ConsentKey.TCF];
var uspString = consents[ConsentKey.USP];
var gppString = consents[ConsentKey.GPP];

// Querying isUserUnderage from AnalyticsEnvironment.
var isUserUnderage = ChartboostCore.AnalyticsEnvironment.IsUserUnderage;

// Subscribing to consent changes.
ChartboostCore.Consent.ConsentChangeWithFullConsents += (fullConsents, keys) =>
{
    Debug.Log($"Consent changed for {keys}");
};

Handling Multiple Initializations 🔗

It is possible that the module’s initialization method may be invoked multiple times.

This usually occurs when the Core SDK attempts to initialize the module, and the module reports back a failure. The Core SDK will attempt to retry module initialization on an exponential backoff up to the maximum number of attempts.

As a module developer, it is good practice to add safeguards to your module initialization implementation so that you can guard against the multiple initialization edge cases such as:

  • Initializing an already initialized module.
  • Cleaning up state after failed module initializations.

Module API Access Before Module Initialization 🔗

Any public API may be called by a Publisher before the module has initialized.

It is good practice to identify which public APIs can function without the module being initialized vs APIs that cannot function without being initialized. For the public APIs that cannot function without being initialized, be sure to put in a fast fail initialization check.