cloudx_flutter 0.18.0 copy "cloudx_flutter: ^0.18.0" to clipboard
cloudx_flutter: ^0.18.0 copied to clipboard

Complete Flutter SDK wrapper for CloudX Core with privacy compliance (CCPA/COPPA/GPP), targeting APIs, and full ad lifecycle callbacks

CloudX Flutter SDK #

pub package GitHub

A Flutter plugin for the CloudX Mobile Ads platform. Monetize your Flutter apps with banner, MREC, and interstitial ads on Android.

Features #

  • Banner Ads (320x50) - Widget-based and programmatic positioning
  • MREC Ads (300x250) - Medium Rectangle ads with flexible placement
  • Interstitial Ads - Full-screen ads for natural transition points
  • Privacy Compliance - Built-in support for CCPA, GPP, and COPPA
  • Auto-Refresh - Automatic ad refresh with server-side configuration
  • Revenue Tracking - Access to eCPM and winning bidder information
  • User Targeting - First-party data integration via key-value pairs

Platform Support #

Platform Status Minimum Version
Android ✅ Production Ready API 21 (Android 5.0)
iOS ❌ Not Supported iOS 14.0

Note: iOS SDK is not yet available for production use.

Installation #

Add this to your pubspec.yaml:

dependencies:
  cloudx_flutter: ^0.18.0

Then run:

flutter pub get

Android Setup #

No additional configuration required. Minimum SDK is automatically set to API 21.

Ad Network Adapters (Android) #

The CloudX SDK requires ad network adapters to serve ads. Adapters are not included by default - you must add them to your project based on which ad networks you want to support.

Add adapters to your app's android/app/build.gradle:

dependencies {
    // CloudX Adapters - add the adapters you want to use
    implementation 'io.cloudx:adapter-meta:0.8.0'      // Meta Audience Network
    implementation 'io.cloudx:adapter-cloudx:0.8.0'    // CloudX Network
    // Add other adapters as needed
}

Or if using Kotlin DSL (build.gradle.kts):

dependencies {
    // CloudX Adapters - add the adapters you want to use
    implementation("io.cloudx:adapter-meta:0.8.0")      // Meta Audience Network
    implementation("io.cloudx:adapter-cloudx:0.8.0")    // CloudX Network
    // Add other adapters as needed
}

Available Adapters:

  • Meta Audience Network - adapter-meta
  • CloudX Network - adapter-cloudx
  • More adapters coming soon

Quick Start #

1. Initialize the SDK #

Initialize CloudX before creating any ads:

import 'package:cloudx_flutter/cloudx.dart';

// Optional: Enable verbose logging (development only)
await CloudX.setLoggingEnabled(true);

// Optional: Set environment (default: production)
await CloudX.setEnvironment('production'); // 'dev', 'staging', or 'production'

// Initialize the SDK
final success = await CloudX.initialize(
  appKey: 'YOUR_APP_KEY',
  testMode: false, // Set to true to enable test ads (development only)
);

if (success) {
  print('CloudX SDK initialized successfully');
} else {
  print('Failed to initialize CloudX SDK');
}

2. Banner Ads #

Option A: Widget-Based (Recommended)

Embed banner ads directly in your widget tree:

import 'package:cloudx_flutter/cloudx.dart';

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('My App')),
      body: Column(
        children: [
          Expanded(child: Text('Your content here')),

          // Banner ad at the bottom
          CloudXBannerView(
            placementName: 'home_banner',
            listener: CloudXAdViewListener(
              onAdLoaded: (ad) => print('Banner loaded: ${ad.bidder}'),
              onAdLoadFailed: (error) => print('Banner failed: $error'),
              onAdDisplayed: (ad) => print('Banner displayed'),
              onAdDisplayFailed: (error) => print('Display failed: $error'),
              onAdClicked: (ad) => print('Banner clicked'),
              onAdHidden: (ad) => print('Banner hidden'),
              onAdExpanded: (ad) => print('Banner expanded'),
              onAdCollapsed: (ad) => print('Banner collapsed'),
            ),
          ),
        ],
      ),
    );
  }
}

Option B: Programmatic Positioning

Create banners that overlay your content at specific screen positions:

// Create a banner ad
final adId = await CloudX.createBanner(
  placementName: 'home_banner',
  adId: 'banner_1', // Optional: auto-generated if not provided
  listener: CloudXAdViewListener(
    onAdLoaded: (ad) => print('Loaded: ${ad.revenue}'),
    onAdLoadFailed: (error) => print('Failed: $error'),
    onAdDisplayed: (ad) => print('Displayed'),
    onAdDisplayFailed: (error) => print('Failed to display'),
    onAdClicked: (ad) => print('Clicked'),
    onAdHidden: (ad) => print('Hidden'),
    onAdExpanded: (ad) => print('Expanded'),
    onAdCollapsed: (ad) => print('Collapsed'),
  ),
  position: AdViewPosition.bottomCenter, // Optional: for overlay banners
);

// Load the banner
await CloudX.loadBanner(adId: adId!);

// Show the banner (if using programmatic positioning)
await CloudX.showBanner(adId: adId);

// Hide when needed
await CloudX.hideBanner(adId: adId);

// Always destroy when done
await CloudX.destroyAd(adId: adId);

Auto-Refresh Control:

// Start auto-refresh (refresh interval configured server-side)
await CloudX.startAutoRefresh(adId: adId);

// Stop auto-refresh (IMPORTANT: call before destroying)
await CloudX.stopAutoRefresh(adId: adId);

3. MREC Ads (300x250) #

Medium Rectangle ads work just like banners but with a larger size.

Widget-Based:

CloudXMRECView(
  placementName: 'home_mrec',
  listener: CloudXAdViewListener(
    onAdLoaded: (ad) => print('MREC loaded'),
    onAdLoadFailed: (error) => print('MREC failed: $error'),
    onAdDisplayed: (ad) => print('MREC displayed'),
    onAdDisplayFailed: (error) => print('Display failed'),
    onAdClicked: (ad) => print('MREC clicked'),
    onAdHidden: (ad) => print('MREC hidden'),
    onAdExpanded: (ad) => print('MREC expanded'),
    onAdCollapsed: (ad) => print('MREC collapsed'),
  ),
)

Programmatic:

final adId = await CloudX.createMREC(
  placementName: 'home_mrec',
  listener: CloudXAdViewListener(...),
  position: AdViewPosition.centered,
);

await CloudX.loadMREC(adId: adId!);
await CloudX.showMREC(adId: adId);

// Check if ready
final isReady = await CloudX.isMRECReady(adId: adId);

// Always destroy when done
await CloudX.destroyAd(adId: adId);

4. Interstitial Ads #

Full-screen ads shown at natural transition points:

// Create the interstitial
final adId = await CloudX.createInterstitial(
  placementName: 'level_complete',
  listener: CloudXInterstitialListener(
    onAdLoaded: (ad) => print('Interstitial ready'),
    onAdLoadFailed: (error) => print('Load failed: $error'),
    onAdDisplayed: (ad) => print('Interstitial showing'),
    onAdDisplayFailed: (error) => print('Show failed: $error'),
    onAdClicked: (ad) => print('Interstitial clicked'),
    onAdHidden: (ad) => print('Interstitial closed'),
  ),
);

// Load the interstitial
await CloudX.loadInterstitial(adId: adId!);

// Check if ready before showing
final isReady = await CloudX.isInterstitialReady(adId: adId);
if (isReady) {
  await CloudX.showInterstitial(adId: adId);
}

// Always destroy after showing
await CloudX.destroyAd(adId: adId);

Event Listeners #

All ad types use listener objects with callback functions.

CloudXAdViewListener #

Used for Banner and MREC ads:

CloudXAdViewListener(
  onAdLoaded: (CloudXAd ad) {
    // Ad successfully loaded
    print('Bidder: ${ad.bidder}');
    print('Revenue: \$${ad.revenue}');
  },
  onAdLoadFailed: (String error) {
    // Failed to load ad
  },
  onAdDisplayed: (CloudXAd ad) {
    // Ad is now visible to user
  },
  onAdDisplayFailed: (String error) {
    // Failed to display ad
  },
  onAdClicked: (CloudXAd ad) {
    // User clicked the ad
  },
  onAdHidden: (CloudXAd ad) {
    // Ad was hidden
  },
  onAdRevenuePaid: (CloudXAd ad) {
    // Revenue tracking (optional)
  },
  onAdExpanded: (CloudXAd ad) {
    // User expanded the ad
  },
  onAdCollapsed: (CloudXAd ad) {
    // User collapsed the ad
  },
)

CloudXInterstitialListener #

Used for Interstitial ads:

CloudXInterstitialListener(
  onAdLoaded: (CloudXAd ad) {
    // Interstitial ready to show
  },
  onAdLoadFailed: (String error) {
    // Failed to load
  },
  onAdDisplayed: (CloudXAd ad) {
    // Interstitial is showing
  },
  onAdDisplayFailed: (String error) {
    // Failed to show
  },
  onAdClicked: (CloudXAd ad) {
    // User clicked
  },
  onAdHidden: (CloudXAd ad) {
    // User closed interstitial
  },
  onAdRevenuePaid: (CloudXAd ad) {
    // Revenue tracking (optional)
  },
)

CloudXAd Model #

All callbacks receive a CloudXAd object with ad metadata:

class CloudXAd {
  final String? placementName;       // Your placement name
  final String? placementId;         // CloudX internal ID
  final String? bidder;              // Winning network (e.g., "meta", "admob")
  final String? externalPlacementId; // Network-specific ID
  final double? revenue;             // eCPM revenue in USD
}

Ad Positioning #

When using programmatic positioning, specify where ads should appear:

enum AdViewPosition {
  topCenter,
  topRight,
  centered,
  centerLeft,
  centerRight,
  bottomLeft,
  bottomCenter,
  bottomRight,
}

Example:

await CloudX.createBanner(
  placementName: 'banner',
  position: AdViewPosition.bottomCenter,
);

Privacy & Compliance #

CloudX provides comprehensive privacy APIs to comply with regulations.

CCPA (California Consumer Privacy Act) #

Fully supported in bid requests:

// Set CCPA privacy string (format: "1YNN")
// 1 = version, Y/N = opt-out-sale, Y/N = opt-out-sharing, Y/N = LSPA
await CloudX.setCCPAPrivacyString('1YNN');

COPPA (Children's Online Privacy Protection Act) #

Clears user data but not yet included in bid requests (server limitation):

await CloudX.setIsAgeRestrictedUser(true); // true = age-restricted

GPP (Global Privacy Platform) #

Comprehensive privacy framework (fully supported):

// Set GPP string
await CloudX.setGPPString('DBABMA~CPXxRfAPXxRfAAfKABENB...');

// Set section IDs (e.g., [7, 8] for US-National and US-CA)
await CloudX.setGPPSid([7, 8]);

// Get current values
final gppString = await CloudX.getGPPString();
final gppSid = await CloudX.getGPPSid();

User Targeting #

Enhance ad targeting with first-party data.

User ID #

// Set user ID (should be hashed for privacy)
await CloudX.setUserID('hashed-user-id');

Key-Value Targeting #

User-Level Targeting (cleared by privacy regulations):

await CloudX.setUserKeyValue('age', '25');
await CloudX.setUserKeyValue('interests', 'gaming');

App-Level Targeting (persistent across privacy changes):

await CloudX.setAppKeyValue('app_version', '1.2.0');
await CloudX.setAppKeyValue('build_type', 'release');

Clear All:

await CloudX.clearAllKeyValues();

Lifecycle Management #

Widget Lifecycle #

For widget-based ads (CloudXBannerView, CloudXMRECView), the SDK automatically handles lifecycle.

Programmatic Lifecycle #

For programmatically created ads, always call destroyAd() to prevent memory leaks:

class MyAdScreen extends StatefulWidget {
  @override
  _MyAdScreenState createState() => _MyAdScreenState();
}

class _MyAdScreenState extends State<MyAdScreen> {
  String? _adId;

  @override
  void initState() {
    super.initState();
    _loadAd();
  }

  Future<void> _loadAd() async {
    _adId = await CloudX.createInterstitial(
      placementName: 'my_interstitial',
      listener: CloudXInterstitialListener(...),
    );
    await CloudX.loadInterstitial(adId: _adId!);
  }

  @override
  void dispose() {
    // CRITICAL: Always destroy ads
    if (_adId != null) {
      CloudX.destroyAd(adId: _adId!);
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(...);
  }
}

SDK Information #

// Check platform support
final isSupported = await CloudX.isPlatformSupported();

// Get SDK version
final version = await CloudX.getVersion();

Advanced Features #

Widget Controllers #

Control banner/MREC widgets programmatically:

final controller = CloudXAdViewController();

CloudXBannerView(
  placementName: 'home_banner',
  controller: controller,
  listener: CloudXAdViewListener(...),
)

// Control auto-refresh
await controller.startAutoRefresh();
await controller.stopAutoRefresh();

// Check if controller is attached
if (controller.isAttached) {
  // Controller is ready
}

Best Practices #

1. Always Destroy Ads #

Memory leaks occur if you don't destroy ads:

@override
void dispose() {
  CloudX.destroyAd(adId: myAdId);
  super.dispose();
}

2. Stop Auto-Refresh Before Destroying #

For banner/MREC ads:

await CloudX.stopAutoRefresh(adId: adId);
await CloudX.destroyAd(adId: adId);

3. Check Ad Readiness #

For interstitials, always check before showing:

final isReady = await CloudX.isInterstitialReady(adId: adId);
if (isReady) {
  await CloudX.showInterstitial(adId: adId);
}

4. Disable Logging in Production #

// Only enable during development
if (kDebugMode) {
  await CloudX.setLoggingEnabled(true);
}

5. Handle Initialization Errors #

final success = await CloudX.initialize(appKey: 'YOUR_KEY');
if (!success) {
  // Handle initialization failure
  // - Check network connection
  // - Verify app key is correct
  // - Check platform support (iOS is not currently supported)
}

Common Issues #

iOS: SDK Not Supported #

Note: iOS SDK is currently not available for production use. The SDK will return false during initialization on iOS.

Checklist:

  1. Did you call loadBanner()?
  2. For programmatic banners, did you call showBanner()?
  3. Is the ad view added to the widget tree?
  4. Check the onAdLoadFailed callback for errors

Memory Leaks #

Solution: Always call destroyAd() in your widget's dispose() method.

Auto-Refresh Not Stopping #

Solution: Explicitly call stopAutoRefresh() before destroying:

await CloudX.stopAutoRefresh(adId: adId);
await CloudX.destroyAd(adId: adId);

Example App #

A complete demo app is available in the GitHub repository under cloudx_flutter_demo_app/. It demonstrates:

  • SDK initialization with environment selection
  • All ad format implementations
  • Widget-based and programmatic approaches
  • Privacy compliance integration
  • User targeting setup
  • Proper lifecycle management
  • Event logging and debugging

Clone the repository and run the demo:

git clone https://github.com/cloudx-io/cloudx-flutter.git
cd cloudx-flutter/cloudx_flutter_demo_app
flutter pub get
flutter run

Requirements #

Flutter #

  • Flutter SDK: 3.0.0 or higher
  • Dart SDK: 3.0.0 or higher

Android #

  • Android API: 21 (Android 5.0) or higher
  • Gradle: 8.0+
  • CloudX Android SDK: 0.8.0

iOS #

Note: iOS is not currently supported. The SDK will compile on iOS but all ad operations will fail gracefully.

API Reference #

Initialization #

  • initialize({required String appKey, bool testMode})Future<bool>
  • isPlatformSupported()bool
  • getVersion()Future<String>
  • setEnvironment(String environment)Future<void>
  • setLoggingEnabled(bool enabled)Future<void>
  • createBanner({required String placementName, String? adId, CloudXAdViewListener? listener, AdViewPosition? position})Future<String?>
  • loadBanner({required String adId})Future<bool>
  • showBanner({required String adId})Future<bool>
  • hideBanner({required String adId})Future<bool>
  • startAutoRefresh({required String adId})Future<bool>
  • stopAutoRefresh({required String adId})Future<bool>

MREC Ads #

  • createMREC({required String placementName, String? adId, CloudXAdViewListener? listener, AdViewPosition? position})Future<String?>
  • loadMREC({required String adId})Future<bool>
  • showMREC({required String adId})Future<bool>
  • isMRECReady({required String adId})Future<bool>

Interstitial Ads #

  • createInterstitial({required String placementName, String? adId, CloudXInterstitialListener? listener})Future<String?>
  • loadInterstitial({required String adId})Future<bool>
  • showInterstitial({required String adId})Future<bool>
  • isInterstitialReady({required String adId})Future<bool>

Ad Lifecycle #

  • destroyAd({required String adId})Future<bool>

Privacy #

  • setCCPAPrivacyString(String? ccpaString)Future<void>
  • setIsUserConsent(bool hasConsent)Future<void>
  • setIsAgeRestrictedUser(bool isAgeRestricted)Future<void>
  • setGPPString(String? gppString)Future<void>
  • getGPPString()Future<String?>
  • setGPPSid(List<int>? sectionIds)Future<void>
  • getGPPSid()Future<List<int>?>

User Targeting #

  • setUserID(String? userID)Future<void>
  • setUserKeyValue(String key, String value)Future<void>
  • setAppKeyValue(String key, String value)Future<void>
  • clearAllKeyValues()Future<void>

Roadmap (Future Versions) #

The following features are planned for future releases:

  • ✅ Rewarded Ads (implementation exists, needs public API)
  • ✅ Native Ads with multiple sizes (implementation exists, needs public API)
  • ✅ Structured error handling with error codes
  • ✅ Granular log level control
  • ✅ App Open Ads

Support #

For questions, issues, or feature requests:

  • Check the demo app for implementation examples
  • Review the API Reference section above

License #

This project is licensed under the MIT License. See the LICENSE file for details.

4
likes
150
points
517
downloads

Publisher

unverified uploader

Weekly Downloads

Complete Flutter SDK wrapper for CloudX Core with privacy compliance (CCPA/COPPA/GPP), targeting APIs, and full ad lifecycle callbacks

Repository (GitHub)
View/report issues

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

ffi, flutter

More

Packages that depend on cloudx_flutter

Packages that implement cloudx_flutter