cloudx_flutter 2.2.3
cloudx_flutter: ^2.2.3 copied to clipboard
Complete Flutter SDK wrapper for CloudX Core with targeting APIs and full ad lifecycle callbacks
CloudX Flutter SDK #
A Flutter plugin for the CloudX Mobile Ads platform. Monetize your Flutter apps with banner, MREC, interstitial, and rewarded ads on Android and iOS.
Installation #
Requires Flutter 3.24.0+, Dart 3.0.0+, Android API 23+, and iOS 13.0+.
Add this to your pubspec.yaml:
dependencies:
cloudx_flutter: ^2.2.3
Then run:
flutter pub get
Android Setup #
No additional configuration required. Minimum SDK is automatically set to API 23.
Add ad network adapters to your app's android/app/build.gradle:
dependencies {
// Adapters for ad networks
implementation("io.cloudx:adapter-meta:2.0.0") // Meta Audience Network 6.21.0
implementation("io.cloudx:adapter-vungle:2.0.0") // Vungle SDK 7.6.1
implementation("io.cloudx:adapter-inmobi:2.0.0") // InMobi SDK 11.1.0
}
iOS Setup #
No additional configuration required. The CloudX SDK is included via CocoaPods automatically.
Add ad network adapter pods to your app's ios/Podfile inside the target 'Runner' do block:
target 'Runner' do
use_frameworks! :linkage => :static
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
# Adapters for ad networks (add as needed)
pod 'CloudXMetaAdapter' # Meta Audience Network 6.21.0
pod 'CloudXVungleAdapter' # Vungle SDK 7.6.0
pod 'CloudXInMobiAdapter' # InMobi SDK 11.1.0
end
Then run cd ios && pod install.
Initialization #
Initialize CloudX before creating any ads:
import 'package:cloudx_flutter/cloudx.dart';
// Optional: Enable verbose logging (development only)
CloudX.setMinLogLevel(CloudXLogLevel.verbose);
// Initialize the SDK
final configuration = await CloudX.initialize(
appKey: 'YOUR_APP_KEY',
);
if (configuration != null) {
print('CloudX SDK initialized successfully');
} else {
print('Failed to initialize CloudX SDK');
}
Ad Integration #
Banner Ads (320x50) #
Banners use the programmatic overlay approach — they overlay your content at a fixed screen position and stay in place while content scrolls underneath.
const adUnitId = 'home_banner';
// Set up listener before creating ads
CloudX.setBannerListener(CloudXAdViewListener(
onAdLoaded: (ad) => print('Banner loaded from ${ad.networkName}'),
onAdLoadFailed: (adUnitId, error) => print('Failed: ${error.message}'),
onAdClicked: (ad) => print('Clicked'),
onAdExpanded: (ad) => print('Expanded'),
onAdCollapsed: (ad) => print('Collapsed'),
onAdRevenuePaid: (ad) => print('Revenue: ${ad.revenue}'), // optional
));
// Create and show
CloudX.createBanner(
adUnitId: adUnitId,
position: CloudXAdViewPosition.bottomCenter,
);
CloudX.showBanner(adUnitId: adUnitId);
// Hide when needed
CloudX.hideBanner(adUnitId: adUnitId);
// Always destroy when done (e.g., in dispose)
CloudX.destroyBanner(adUnitId: adUnitId);
Banner ads auto-refresh by default. To control refresh manually:
CloudX.stopBannerAutoRefresh(adUnitId: adUnitId);
CloudX.loadBanner(adUnitId: adUnitId); // Manually load a new ad
CloudX.startBannerAutoRefresh(adUnitId: adUnitId); // Re-enable auto-refresh
Optional placement and custom data for tracking:
CloudX.setBannerPlacement(adUnitId: adUnitId, placement: 'home_screen');
CloudX.setBannerCustomData(adUnitId: adUnitId, customData: 'level:5,coins:100');
You can update position without recreating:
CloudX.updateBannerPosition(
adUnitId: adUnitId,
position: CloudXAdViewPosition.topCenter,
);
MREC Ads (300x250) #
MREC ads work identically to banners but with a larger size. Set up a separate listener with CloudX.setMRecListener(...).
const adUnitId = 'home_mrec';
CloudX.setMRecListener(CloudXAdViewListener(
onAdLoaded: (ad) => print('MREC loaded from ${ad.networkName}'),
onAdLoadFailed: (adUnitId, error) => print('Failed: ${error.message}'),
onAdClicked: (ad) => print('Clicked'),
onAdExpanded: (ad) => print('Expanded'),
onAdCollapsed: (ad) => print('Collapsed'),
onAdRevenuePaid: (ad) => print('Revenue: ${ad.revenue}'), // optional
));
CloudX.createMREC(
adUnitId: adUnitId,
position: CloudXAdViewPosition.centered,
);
CloudX.showMREC(adUnitId: adUnitId);
// Always destroy when done (e.g., in dispose)
CloudX.destroyMREC(adUnitId: adUnitId);
MREC ads also auto-refresh by default. Use the same refresh control methods as banner ads.
Widget-Based Ads (Inline) #
For ads that embed in the Flutter widget tree and scroll with content, use the CloudXAdView widget instead of the programmatic overlay APIs above.
CloudXAdView(
adUnitId: 'feed_banner',
adFormat: CloudXAdFormat.banner, // or CloudXAdFormat.mrec
listener: CloudXAdViewListener(
onAdLoaded: (ad) => print('Loaded from ${ad.networkName}'),
onAdLoadFailed: (adUnitId, error) => print('Failed: ${error.message}'),
onAdClicked: (ad) => print('Clicked'),
onAdExpanded: (ad) => print('Expanded'),
onAdCollapsed: (ad) => print('Collapsed'),
onAdRevenuePaid: (ad) => print('Revenue: ${ad.revenue}'),
),
)
Key differences from programmatic overlay ads:
- Embeds inline in the widget tree (scrolls with content)
- Each widget has its own per-instance listener (not global)
- Auto-loads on creation
- Automatically destroyed when the widget is removed from the tree
Auto-refresh is enabled by default. Control it via the isAutoRefreshEnabled parameter:
CloudXAdView(
adUnitId: 'feed_banner',
adFormat: CloudXAdFormat.banner,
isAutoRefreshEnabled: false, // disable auto-refresh
)
Changing isAutoRefreshEnabled dynamically (e.g., via setState) will start or stop auto-refresh without recreating the ad view.
Interstitial Ads #
Full-screen ads shown at natural transition points.
Note: Interstitials don't need a create call. The loadInterstitial method auto-creates the instance.
const adUnitId = 'level_complete';
CloudX.setInterstitialListener(CloudXInterstitialListener(
onAdLoaded: (ad) => print('Interstitial loaded'),
onAdLoadFailed: (adUnitId, error) => print('Failed: ${error.message}'),
onAdDisplayed: (ad) => print('Displayed'),
onAdDisplayFailed: (ad, error) => print('Display failed: ${error.message}'),
onAdClicked: (ad) => print('Clicked'),
onAdHidden: (ad) {
print('Hidden');
// Reload for next use
CloudX.loadInterstitial(adUnitId: adUnitId);
},
onAdRevenuePaid: (ad) => print('Revenue: ${ad.revenue}'), // optional
));
// Load
CloudX.loadInterstitial(adUnitId: adUnitId);
// Check if ready before showing
final isReady = await CloudX.isInterstitialReady(adUnitId: adUnitId);
if (isReady) {
CloudX.showInterstitial(adUnitId: adUnitId);
// Or with optional placement and custom data for tracking
// CloudX.showInterstitial(adUnitId: adUnitId, placement: 'level_complete', customData: 'level:5');
}
// Always destroy when done (e.g., in dispose)
CloudX.destroyInterstitial(adUnitId: adUnitId);
Rewarded Ads #
Full-screen ads that grant users a reward upon completion.
Note: Like interstitials, rewarded ads don't need a create call. The loadRewardedAd method auto-creates the instance.
const adUnitId = 'rewarded_coins';
CloudX.setRewardedAdListener(CloudXRewardedListener(
onAdLoaded: (ad) => print('Rewarded loaded'),
onAdLoadFailed: (adUnitId, error) => print('Failed: ${error.message}'),
onAdDisplayed: (ad) => print('Displayed'),
onAdDisplayFailed: (ad, error) => print('Display failed: ${error.message}'),
onAdClicked: (ad) => print('Clicked'),
onAdHidden: (ad) {
print('Hidden');
// Reload for next use
CloudX.loadRewardedAd(adUnitId: adUnitId);
},
onAdReceivedReward: (ad, reward) {
print('Earned ${reward.amount} ${reward.label}');
// Grant the reward to the user
},
onAdRevenuePaid: (ad) => print('Revenue: ${ad.revenue}'), // optional
));
// Load
CloudX.loadRewardedAd(adUnitId: adUnitId);
// Check if ready before showing
final isReady = await CloudX.isRewardedAdReady(adUnitId: adUnitId);
if (isReady) {
CloudX.showRewardedAd(adUnitId: adUnitId);
// Or with optional placement and custom data for tracking
// CloudX.showRewardedAd(adUnitId: adUnitId, placement: 'bonus_coins', customData: 'level:5');
}
// Always destroy when done (e.g., in dispose)
CloudX.destroyRewardedAd(adUnitId: adUnitId);
Ad Information (CloudXAd) #
The CloudXAd object is passed to listener callbacks and contains information about the loaded/displayed ad:
| Property | Type | Description |
|---|---|---|
adFormat |
CloudXAdFormat |
Ad format (banner, mrec, interstitial, rewarded) |
adUnitId |
String |
The ad unit ID |
networkName |
String |
Name of the winning ad network |
networkPlacement |
String? |
Network-specific placement ID |
placement |
String? |
Custom placement set via setPlacement() |
revenue |
double |
Impression-level revenue in USD |
onAdLoaded: (ad) {
print('Ad format: ${ad.adFormat}');
print('Network: ${ad.networkName}');
print('Revenue: ${ad.revenue}');
},
Error Handling #
All SDK errors are returned as CloudXError objects in listener callbacks:
| Property | Type | Description |
|---|---|---|
code |
int |
Error code (see categories below) |
message |
String |
Human-readable description |
Error Code Categories
| Range | Category | Common Codes |
|---|---|---|
| 0 | General | internalError |
| 100-199 | Network | networkError, networkTimeout, networkServerError, networkNoConnection |
| 200-299 | Initialization | notInitialized, sdkDisabled, noAdaptersFound, invalidAppKey |
| 300-399 | Ad Loading | noFill, invalidAdUnit, adsDisabled |
| 400-499 | Display | adNotReady, adAlreadyShowing |
| 600-699 | Adapter | adapterNoFill, adapterTimeout, adapterLoadTimeout, adapterInitializationError |
See CloudXErrorCode for the full list of error codes.
Advanced Features #
Debug Logging #
// Enable verbose logging (call before initialize)
CloudX.setMinLogLevel(CloudXLogLevel.verbose);
// Only enable during development
if (kDebugMode) {
CloudX.setMinLogLevel(CloudXLogLevel.verbose);
}
Impression-Level Revenue Tracking #
Use the optional onAdRevenuePaid callback on any listener to receive impression-level revenue (ILR) data. The CloudXAd object contains the revenue value in USD and the winning network name.
onAdRevenuePaid: (ad) {
print('Revenue: ${ad.revenue} from ${ad.networkName}');
},
Works with all ad formats (banner, MREC, interstitial, rewarded) and widget-based ads.
Test Mode #
Test mode is server-controlled via device whitelisting. This provides better security and control over which devices receive test ads.
To enable test mode:
- Initialize the SDK with logging enabled and check the console for your device advertising ID
- Copy the advertising ID and add it to your device whitelist on the CloudX server dashboard
- The SDK will automatically configure adapters for test mode and include the test flag in bid requests
Note: Test mode is determined by the server, so you don't need to change any code between development and production builds.
Privacy Compliance #
The CloudX SDK supports GDPR and CCPA privacy compliance by reading standard IAB privacy strings from platform storage (SharedPreferences on Android, NSUserDefaults on iOS). These values are typically set automatically by your Consent Management Platform (CMP) such as Google UMP, OneTrust, or Sourcepoint.
How It Works
The SDK automatically detects user location and reads consent signals:
- EU Users (GDPR): Checks TCF v2 consent for purposes 1-4 and vendor consent (CloudX Vendor ID: 1510)
- US Users (CCPA): Checks for sale/sharing opt-out signals
- Other Regions: No restrictions applied
When consent is denied or user opts out, the SDK removes PII from ad requests:
- Advertising ID is cleared
- Geo coordinates (lat/lon) are removed
- User key-values are not sent
- Hashed user ID is excluded
Supported Privacy Keys
| Key | Standard | Description |
|---|---|---|
IABGPP_HDR_GppString |
GPP | Global Privacy Platform string (modern) |
IABGPP_GppSID |
GPP | Section IDs (e.g., "2" for EU, "7" for US-National, "8" for US-CA) |
IABTCF_TCString |
TCF v2 | GDPR consent string (legacy) |
IABTCF_gdprApplies |
TCF v2 | Whether GDPR applies (1 = yes, 0 = no) |
IABUSPrivacy_String |
US Privacy | CCPA privacy string (legacy, e.g., "1YNN") |
Note: The SDK prioritizes GPP (modern standard) over legacy TCF/US Privacy strings when both are available.
User Targeting #
// Set hashed user ID for targeting
CloudX.setHashedUserId('hashed-user-id');
// Set custom user key-value pairs
CloudX.setUserKeyValue('age', '25');
CloudX.setUserKeyValue('interests', 'gaming');
// Set custom app key-value pairs
CloudX.setAppKeyValue('app_version', '1.2.0');
CloudX.setAppKeyValue('build_type', 'release');
// Clear all custom key-values
CloudX.clearAllKeyValues();
Support #
For support, contact mobile@cloudx.io