Skip to main content

CloudX Flutter SDK

pub package The CloudX Flutter SDK enables monetization of your Flutter apps with banner, MREC, interstitial, and rewarded ads on iOS and Android.

Installation

Requirements

These match the published package constraints on pub.dev:
RequirementVersion
Dart SDK>=2.17.1 <4.0.0
Flutter>=3.0.0
iOS13.0+
AndroidminSdk 23 (API 23)
The Dart range is intentionally wide so apps on older Flutter LTS lines can add cloudx_flutter without upgrading the whole toolchain. Add the SDK to your pubspec.yaml:
dependencies:
  cloudx_flutter: ^2.2.3
Then run:
flutter pub get

iOS Setup

Add ad network adapter pods to your ios/Podfile:
target 'Runner' do
  # ... existing config ...

  # CloudX ad network adapters (add as needed; match your native stack version)
  pod 'CloudXMetaAdapter', '~> 2.2.3'
  pod 'CloudXVungleAdapter', '~> 2.2.3'
  pod 'CloudXInMobiAdapter', '~> 2.2.3'
  pod 'CloudXMintegralAdapter', '~> 2.2.3'
  pod 'CloudXUnityAdsAdapter', '~> 2.2.3'
  pod 'CloudXRenderer', '~> 2.2.3'
end
Then install pods:
cd ios && pod install
The CloudXCore pod is automatically included as a dependency of the cloudx_flutter package. You only need to add the adapter pods you want.

App Transport Security

If your ads use HTTP URLs, add the following to your ios/Runner/Info.plist:
<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

Android Setup

Add CloudX SDK and adapter dependencies to your app module — typically android/app/build.gradle or android/app/build.gradle.kts:
dependencies {
    // CloudX Android SDK (version should match cloudx_flutter’s pinned native release)
    implementation("io.cloudx:sdk:2.2.3")

    // Adapters for ad networks (add as needed)
    implementation("io.cloudx:adapter-meta:2.2.3")
    implementation("io.cloudx:adapter-vungle:2.2.3")
    implementation("io.cloudx:adapter-inmobi:2.2.3")
    implementation("io.cloudx:adapter-mintegral:2.2.3")
    implementation("io.cloudx:adapter-unityads:2.2.3")
}
At least one adapter is required for the SDK to serve ads. Remove adapter lines you do not use.

Mintegral adapter and Maven repository

If you include io.cloudx:adapter-mintegral, Gradle must resolve Mintegral’s SDK from Mintegral’s own Maven server (not Maven Central). Add their repository in your Android Gradle repositories configuration (usually the project-level build.gradle / build.gradle.kts, e.g. inside allprojects { repositories { … } } in Flutter apps). Full steps, Kotlin/Groovy snippets, and troubleshooting are in the Android integration guide — Mintegral Maven repository.

Initialization

Initialize the SDK before loading any ads. Typically in your main widget’s initState:
import 'package:cloudx_flutter/cloudx.dart';

// Optional: enable verbose logging (development only)
CloudX.setMinLogLevel(CloudXLogLevel.verbose);

// Initialize with your app key
final config = await CloudX.initialize(appKey: 'YOUR_APP_KEY');
if (config != null) {
  print('CloudX initialized');
} else {
  print('CloudX init failed');
}
CloudX.initialize() returns a non-null CloudXConfiguration on success, or null on failure. The configuration object has no properties today—use the return value only as a success signal. Other initialization utilities:
final initialized = await CloudX.isInitialized();
final version = await CloudX.getVersion();

Ad Integration

Banners use the programmatic overlay approach — they overlay your content at a fixed screen position.
import 'package:cloudx_flutter/cloudx.dart';

const adUnitId = 'home_banner';

// Set up event listener
CloudX.setBannerListener(CloudXAdViewListener(
  onAdLoaded: (ad) {
    print('Banner loaded from ${ad.networkName}');
  },
  onAdLoadFailed: (adUnitId, error) {
    print('Banner failed: ${error.code} ${error.message}');
  },
  onAdClicked: (ad) {
    print('Banner clicked');
  },
  onAdRevenuePaid: (ad) {
    print('Banner revenue: ${ad.revenue}');
  },
));

// Create and show
CloudX.createBanner(adUnitId: adUnitId, position: CloudXAdViewPosition.bottomCenter);
CloudX.showBanner(adUnitId: adUnitId);

// Hide / destroy when done
CloudX.hideBanner(adUnitId: adUnitId);
CloudX.destroyBanner(adUnitId: adUnitId);
Auto-refresh is enabled by default. To control it manually:
CloudX.stopBannerAutoRefresh(adUnitId: adUnitId);
CloudX.startBannerAutoRefresh(adUnitId: adUnitId);
Use CloudXAdViewPosition to place the banner: topLeft, topCenter, topRight, centerLeft, centered, centerRight, bottomLeft, bottomCenter, bottomRight To update the position after creation:
CloudX.updateBannerPosition(adUnitId: adUnitId, position: CloudXAdViewPosition.topCenter);

Additional Banner APIs

CloudX.setBannerPlacement(adUnitId: adUnitId, placement: 'home_screen');
CloudX.setBannerCustomData(adUnitId: adUnitId, customData: 'custom_data');
CloudX.loadBanner(adUnitId: adUnitId); // manual reload
CallbackType
onAdLoadedCloudXAd
onAdLoadFailedString adUnitId, CloudXError
onAdClickedCloudXAd
onAdExpandedCloudXAd (optional)
onAdCollapsedCloudXAd (optional)
onAdRevenuePaidCloudXAd (optional)

MREC Ads (300x250)

MRECs work identically to banners but with a 300x250 size. Use the MREC methods:
const adUnitId = 'home_mrec';

CloudX.setMRecListener(CloudXAdViewListener(
  onAdLoaded: (ad) {
    print('MREC loaded from ${ad.networkName}');
  },
  onAdLoadFailed: (adUnitId, error) {
    print('MREC failed: ${error.code} ${error.message}');
  },
));

CloudX.createMREC(adUnitId: adUnitId, position: CloudXAdViewPosition.centered);
CloudX.showMREC(adUnitId: adUnitId);

// Destroy when done
CloudX.destroyMREC(adUnitId: adUnitId);
The MREC API is identical to the Banner API — all the same methods and events are available, including updateMRECPosition, setMRECPlacement, setMRECCustomData, auto-refresh control, and all event listeners.

Interstitial Ads

Full-screen ads shown at natural transition points.
import 'package:cloudx_flutter/cloudx.dart';

const adUnitId = 'level_complete';

// Set up event listener
CloudX.setInterstitialListener(CloudXInterstitialListener(
  onAdLoaded: (ad) {
    print('Interstitial loaded');
  },
  onAdLoadFailed: (adUnitId, error) {
    print('Interstitial load failed: ${error.code} ${error.message}');
  },
  onAdDisplayed: (ad) {
    print('Interstitial displayed');
  },
  onAdDisplayFailed: (ad, error) {
    print('Interstitial display failed: ${error.code} ${error.message}');
  },
  onAdHidden: (ad) {
    // Reload for next use
    CloudX.loadInterstitial(adUnitId: adUnitId);
  },
  onAdClicked: (ad) {
    print('Interstitial clicked');
  },
  onAdRevenuePaid: (ad) {
    print('Revenue: ${ad.revenue}');
  },
));

// Load
CloudX.loadInterstitial(adUnitId: adUnitId);

// Show when ready (with optional placement and custom data)
final isReady = await CloudX.isInterstitialReady(adUnitId: adUnitId);
if (isReady) {
  CloudX.showInterstitial(adUnitId: adUnitId);
  // or: CloudX.showInterstitial(adUnitId: adUnitId, placement: 'placement_name', customData: 'custom_data');
}

// Destroy when done
CloudX.destroyInterstitial(adUnitId: adUnitId);

Interstitial Events

CallbackType
onAdLoadedCloudXAd
onAdLoadFailedString adUnitId, CloudXError
onAdDisplayedCloudXAd
onAdDisplayFailedCloudXAd, CloudXError
onAdClickedCloudXAd
onAdHiddenCloudXAd
onAdRevenuePaidCloudXAd (optional)

Rewarded Ads

Full-screen ads that grant users a reward upon completion.
import 'package:cloudx_flutter/cloudx.dart';

const adUnitId = 'rewarded_coins';

// Set up event listener
CloudX.setRewardedAdListener(CloudXRewardedListener(
  onAdLoaded: (ad) {
    print('Rewarded loaded');
  },
  onAdLoadFailed: (adUnitId, error) {
    print('Rewarded load failed: ${error.code} ${error.message}');
  },
  onAdDisplayed: (ad) {
    print('Rewarded displayed');
  },
  onAdDisplayFailed: (ad, error) {
    print('Rewarded display failed: ${error.code} ${error.message}');
  },
  onAdReceivedReward: (ad, reward) {
    print('Earned ${reward.amount} ${reward.label}');
  },
  onAdHidden: (ad) {
    // Reload for next use
    CloudX.loadRewardedAd(adUnitId: adUnitId);
  },
  onAdClicked: (ad) {
    print('Rewarded clicked');
  },
  onAdRevenuePaid: (ad) {
    print('Revenue: ${ad.revenue}');
  },
));

// Load
CloudX.loadRewardedAd(adUnitId: adUnitId);

// Show when ready (with optional placement and custom data)
final isReady = await CloudX.isRewardedAdReady(adUnitId: adUnitId);
if (isReady) {
  CloudX.showRewardedAd(adUnitId: adUnitId);
  // or: CloudX.showRewardedAd(adUnitId: adUnitId, placement: 'placement_name', customData: 'custom_data');
}

// Destroy when done
CloudX.destroyRewardedAd(adUnitId: adUnitId);

Rewarded Events

CallbackType
onAdLoadedCloudXAd
onAdLoadFailedString adUnitId, CloudXError
onAdDisplayedCloudXAd
onAdDisplayFailedCloudXAd, CloudXError
onAdClickedCloudXAd
onAdHiddenCloudXAd
onAdReceivedRewardCloudXAd, CloudXReward
onAdRevenuePaidCloudXAd (optional)
The CloudXReward object contains:
  • label — the label of the reward (e.g., “coins”)
  • amount — the reward quantity

Widget-Based Ad Views

In addition to the programmatic overlay approach, you can embed banner and MREC ads directly in your widget tree using CloudXAdView:
CloudXAdView(
  adUnitId: 'home_banner',
  adFormat: CloudXAdFormat.banner,
  listener: CloudXAdViewListener(
    onAdLoaded: (ad) => print('Widget banner loaded'),
    onAdLoadFailed: (adUnitId, error) => print('Widget banner failed'),
  ),
)
This uses Flutter’s platform view system (AndroidView / UiKitView) to embed the native ad view inline with your Flutter widgets.

Advanced Features

Error Handling

All error callbacks receive a CloudXError with code and message properties:
RangeCategoryCommon Codes
0GeneralinternalError
100-199NetworknetworkError, networkTimeout, networkServerError, networkNoConnection
200-299InitializationnotInitialized, noAdaptersFound, sdkDisabled, invalidAppKey
300-399Ad LoadingnoFill, invalidAdUnit, adsDisabled
400-499DisplayadNotReady, adAlreadyShowing, dontKeepActivitiesEnabled
600-699AdapteradapterNoFill, adapterLoadTimeout, adapterTimeout, adapterInitializationError
See CloudXErrorCode for the full list of error codes.

Revenue Tracking

All ad formats provide revenue callbacks. CloudXAd includes adUnitId, adFormat, networkName, revenue (USD), optional placement, and optional networkPlacement:
CloudX.setInterstitialListener(CloudXInterstitialListener(
  onAdRevenuePaid: (ad) {
    trackRevenue(ad.revenue, ad.networkName, ad.adUnitId);
  },
  // ... other callbacks
));

User Targeting

import 'package:cloudx_flutter/cloudx.dart';

// Set hashed user ID (pass null to clear)
CloudX.setHashedUserId('hashed-user-id');

// Set custom key-value pairs
CloudX.setUserKeyValue('age_group', '25-34');
CloudX.setAppKeyValue('app_version', '1.0.0');

// Clear all custom key-values
CloudX.clearAllKeyValues();

Privacy Compliance

Reads IAB GPP, TCF v2, and US Privacy strings from NSUserDefaults / SharedPreferences (typically set by a CMP).
KeyStandardDescription
IABGPP_HDR_GppStringGPPGlobal Privacy Platform string
IABGPP_GppSIDGPPSection IDs
IABTCF_TCStringTCF v2GDPR consent string
IABUSPrivacy_StringUS PrivacyCCPA string
Manual APIs: CloudX.setHasUserConsent(bool?) and CloudX.setDoNotSell(bool?) when you do not use a CMP, or to override until cleared. null removes the override; resolution order matches the native SDK (stored IAB strings and these overrides). Callable before CloudX.initialize().
CloudX.setHasUserConsent(true);
CloudX.setDoNotSell(false);
CloudX.setHasUserConsent(null);

Test Mode

Test mode is server-controlled via device whitelisting:
  1. Initialize the SDK with verbose logging enabled
  2. Find your device advertising ID in the console logs
  3. Add the device to your whitelist on the CloudX dashboard

Debug Logging

import 'package:cloudx_flutter/cloudx.dart';

// Enable verbose logging (call before initialize)
CloudX.setMinLogLevel(CloudXLogLevel.verbose);

// Available levels: verbose, debug, info, warn, error, none

Visual Debugging

Enable visual debugging overlays to see ad unit boundaries and network info (iOS only):
CloudX.setVisualDebuggingEnabled(true);

Support

For support, contact mobile@cloudx.io