Yodo SDK Flutter Plugin

A Flutter plugin that integrates Yodo1's Managed Ad Services (MAS) SDK, providing a simple way to display ads in your Flutter applications on both Android and iOS platforms.

📋 Table of Contents

✨ Features

  • Interstitial Ads - Full-screen ads shown between content
  • Rewarded Ads - Users watch ads to earn rewards
  • Rewarded Interstitial Ads - Combination of interstitial and rewarded ads
  • App Open Ads - Ads shown when the app is opened
  • Banner Ads - Small ads displayed at the top or bottom of the screen
  • Native Ads - Customizable ads that match your app's design
  • Privacy Compliance - Built-in support for GDPR, CCPA, and COPPA
  • Placement IDs - Support for custom placement IDs
  • Preloading - Option to preload ads for better performance

📦 Installation

Step 1: Add the dependency

Add yodosdk to your pubspec.yaml file:

dependencies:
  flutter:
    sdk: flutter
  yodosdk: ^1.0.8

Step 2: Install the package

Run the following command in your terminal:

flutter pub get

Step 3: Import the package

In your Dart files, import the package:

import 'package:yodosdk/yodosdk.dart';

🔧 Platform Setup

Android Setup

  1. Minimum SDK Version: Ensure your android/app/build.gradle has:

    minSdkVersion 21
    
  2. Internet Permission: Add internet permission to android/app/src/main/AndroidManifest.xml:

    <uses-permission android:name="android.permission.INTERNET"/>
    
  3. ProGuard Rules (if using ProGuard): Add to android/app/proguard-rules.pro:

    -keep class com.yodo1.** { *; }
    -dontwarn com.yodo1.**
    

iOS Setup

  1. Minimum iOS Version: Ensure your ios/Podfile has:

    platform :ios, '11.0'
    
  2. Info.plist: Add the following to ios/Runner/Info.plist:

    <key>NSUserTrackingUsageDescription</key>
    <string>This identifier will be used to deliver personalized ads to you.</string>
    
  3. Install Pods: Run:

    cd ios
    pod install
    

🚀 Quick Start

Step 1: Get Your App ID

  1. Sign up at Yodo1 MAS Dashboard
  2. Create a new app
  3. Copy your App ID

Step 2: Initialize the SDK

Initialize the SDK in your app's main file (usually main.dart):

import 'package:flutter/material.dart';
import 'package:yodosdk/yodosdk.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    _initializeSDK();
  }

  Future<void> _initializeSDK() async {
    await Yodosdk.initSdk(
      appId: "YOUR_APP_ID_HERE", // Replace with your actual App ID
      preLoadAds: true, // Preload ads for better performance
      showPrivacyDialog: true, // Show privacy dialog to users
      coppa: false, // Set to true if your app targets children
      gdpr: true, // Set GDPR compliance
      ccpa: false, // Set CCPA compliance
      initAdCallback: InitAdCallback(
        onSuccess: () {
          print("✅ SDK initialized successfully!");
          // You can now show ads
        },
        onError: (error) {
          print("❌ SDK initialization failed: $error");
          // Handle initialization error
        },
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      home: HomeScreen(),
    );
  }
}

Important Notes:

  • Replace "YOUR_APP_ID_HERE" with your actual Yodo App ID
  • Always initialize the SDK before showing any ads
  • The onSuccess callback means the SDK is ready to use
  • Handle errors in the onError callback

📖 Implementation Guide

Understanding Callbacks

Callbacks are functions that get called when something happens with an ad. Think of them as notifications:

  • onLoad: The ad finished loading and is ready to show
  • onAdLoadFail: The ad failed to load (maybe no internet or no ads available)
  • onAdOpen: The ad was opened/shown to the user
  • onAdOpenFail: Failed to show the ad
  • onClose: The user closed the ad
  • onRewardEarned: (For reward ads) The user earned a reward

1. Interstitial Ads

Interstitial ads are full-screen ads shown between content (like between game levels).

When to use: Between screens, after completing a task, between game levels

import 'package:yodosdk/yodosdk.dart';

// In your widget or function
void _showInterstitialAd() {
  Yodosdk.loadAndShowInter(
    placementId: "your_placement_id", // Optional: Use custom placement ID
    fullScreenAdCallbacks: FullScreenAdCallbacks(
      onLoad: (adId) {
        print("✅ Interstitial ad loaded: $adId");
        // Ad is ready to show
      },
      onAdLoadFail: (error) {
        print("❌ Interstitial ad failed to load: $error");
        // Handle error - maybe show a message or retry
      },
      onAdOpen: (adId) {
        print("📱 Interstitial ad opened: $adId");
        // Pause your game/app here
      },
      onAdOpenFail: (error) {
        print("❌ Interstitial ad failed to open: $error");
        // Handle error
      },
      onClose: (adId) {
        print("👋 Interstitial ad closed: $adId");
        // Resume your game/app here
        // Give rewards or continue to next level
      },
    ),
  );
}

// Example: Show ad after completing a level
void _onLevelComplete() {
  // Show congratulations message
  _showCongratulations();

  // Show interstitial ad
  _showInterstitialAd();

  // After ad closes, continue to next level
}

2. Rewarded Ads

Rewarded ads let users watch an ad to earn a reward (like extra lives, coins, etc.).

When to use: When user wants extra lives, bonus coins, skip a level, etc.

void _showRewardedAd() {
  Yodosdk.loadAndShowReward(
    placementId: "reward_placement", // Optional
    rewardAdCallbacks: RewardAdCallbacks(
      onLoad: (adId) {
        print("✅ Reward ad loaded: $adId");
      },
      onAdLoadFail: (error) {
        print("❌ Reward ad failed to load: $error");
        // Show message: "Ad not available, please try again later"
      },
      onAdOpen: (adId) {
        print("📱 Reward ad opened: $adId");
        // Pause your app
      },
      onAdOpenFail: (error) {
        print("❌ Reward ad failed to open: $error");
      },
      onClose: (adId) {
        print("👋 Reward ad closed: $adId");
        // Note: User might not have watched the full ad
        // Only give reward if onRewardEarned was called
      },
      onRewardEarned: (adId) {
        print("🎉 Reward earned! Ad ID: $adId");
        // Give reward here (extra lives, coins, etc.)
        _giveReward();
      },
    ),
  );
}

void _giveReward() {
  // Add coins, extra lives, etc.
  setState(() {
    coins += 100;
    lives += 1;
  });

  // Show success message
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(content: Text("You earned 100 coins and 1 extra life!")),
  );
}

// Example: Button to watch ad for extra life
ElevatedButton(
  onPressed: () {
    _showRewardedAd();
  },
  child: Text("Watch Ad for Extra Life"),
)

Important: Only give rewards when onRewardEarned is called, not just when the ad closes!

3. Rewarded Interstitial Ads

Similar to rewarded ads but shown as full-screen interstitials.

void _showRewardedInterstitialAd() {
  Yodosdk.loadAndShowRewardInter(
    rewardAdCallbacks: RewardAdCallbacks(
      onLoad: (adId) => print("✅ Rewarded interstitial loaded"),
      onAdLoadFail: (error) => print("❌ Failed: $error"),
      onAdOpen: (adId) => print("📱 Ad opened"),
      onAdOpenFail: (error) => print("❌ Failed to open: $error"),
      onClose: (adId) => print("👋 Ad closed"),
      onRewardEarned: (adId) {
        print("🎉 Reward earned!");
        _giveReward();
      },
    ),
  );
}

4. App Open Ads

Ads shown when the app is opened (like when user returns to the app).

When to use: When app starts or when user returns from background

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    _initializeSDK();
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      // User returned to the app
      _showAppOpenAd();
    }
  }

  void _showAppOpenAd() {
    Yodosdk.loadAndShowAppOpen(
      fullScreenAdCallbacks: FullScreenAdCallbacks(
        onLoad: (adId) => print("✅ App open ad loaded"),
        onAdLoadFail: (error) => print("❌ Failed: $error"),
        onAdOpen: (adId) => print("📱 App open ad shown"),
        onAdOpenFail: (error) => print("❌ Failed to open: $error"),
        onClose: (adId) => print("👋 App open ad closed"),
      ),
    );
  }
}

5. Banner Ads

Small ads displayed at the top or bottom of the screen.

When to use: On main screens, game menus, etc.

import 'package:yodosdk/yodosdk.dart';

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("My App")),
      body: Column(
        children: [
          // Your app content here
          Expanded(
            child: Center(child: Text("Your App Content")),
          ),

          // Banner ad at the bottom
          Yodosdk.getBanner(
            size: BannerSize.adaptiveBanner, // Adapts to screen width
            bannerAdCallback: BannerAdCallback(
              onLoad: () {
                print("✅ Banner ad loaded");
              },
              onLoadFailed: (error) {
                print("❌ Banner ad failed: $error");
              },
              onOpen: () {
                print("📱 Banner ad clicked");
              },
              onOpenFail: (error) {
                print("❌ Banner ad click failed: $error");
              },
              onClosed: () {
                print("👋 Banner ad closed");
              },
            ),
          ),
        ],
      ),
    );
  }
}

Banner Sizes Available:

  • BannerSize.banner - Standard banner (320x50)
  • BannerSize.largeBanner - Large banner (320x100)
  • BannerSize.adaptiveBanner - Adapts to screen width (recommended)
  • BannerSize.smartBanner - Smart banner (full width, 50px height)
  • BannerSize.iabMediumRectangle - Medium rectangle (300x250)

6. Native Ads

Customizable ads that match your app's design.

When to use: In lists, feeds, or custom layouts

Yodosdk.getNative(
  size: NativeSize.nativeLarge, // or NativeSize.nativeSmall
  nativeAdCallback: NativeAdCallback(
    onLoad: () {
      print("✅ Native ad loaded");
    },
    onLoadFailed: (error) {
      print("❌ Native ad failed: $error");
    },
    onClosed: () {
      print("👋 Native ad closed");
    },
  ),
)

Native Sizes:

  • NativeSize.nativeSmall - Small native ad (300x100)
  • NativeSize.nativeLarge - Large native ad (600x335)

💡 Best Practices

1. Initialize Once

Initialize the SDK only once, preferably in your main() function or app initialization:

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  _initializeSDK(); // Initialize here
  runApp(MyApp());
}

2. Preload Ads

Enable preLoadAds: true during initialization to preload ads for better performance:

await Yodosdk.initSdk(
  appId: "YOUR_APP_ID",
  preLoadAds: true, // Preload ads
  // ...
);

3. Show Ads at Appropriate Times

  • Interstitial Ads: Between levels, after completing tasks, between screens
  • Rewarded Ads: When user wants extra lives, coins, or bonuses
  • Banner Ads: On main screens, menus, or content screens
  • App Open Ads: When app starts or resumes from background

4. Handle Errors Gracefully

Always handle errors in callbacks:

onAdLoadFail: (error) {
  // Don't show error to user, just log it
  print("Ad failed: $error");

  // Optionally show a friendly message
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(content: Text("Ad not available right now")),
  );
}

5. Don't Spam Ads

  • Don't show ads too frequently
  • Give users time between ads
  • Consider user experience

6. Test on Real Devices

Always test on real devices, not just simulators/emulators.

⚠️ Error Handling

Common Errors and Solutions

1. SDK Initialization Failed

Error: SDK initialization failed

Possible Causes:

  • Invalid App ID
  • No internet connection
  • SDK not properly configured

Solution:

initAdCallback: InitAdCallback(
  onSuccess: () {
    print("SDK ready!");
  },
  onError: (error) {
    print("Init error: $error");
    // Check your App ID
    // Check internet connection
    // Check platform setup
  },
),

2. Ad Failed to Load

Error: Ad failed to load

Possible Causes:

  • No ads available
  • No internet connection
  • Ad not ready yet

Solution:

onAdLoadFail: (error) {
  // Log the error
  print("Ad load failed: $error");

  // Don't show error to user
  // Optionally retry after a delay
  Future.delayed(Duration(seconds: 5), () {
    _showAdAgain(); // Retry showing ad
  });
}

3. Ad Failed to Open

Error: Ad failed to open

Possible Causes:

  • Ad was closed before it could open
  • Network issues
  • Ad expired

Solution:

onAdOpenFail: (error) {
  print("Ad open failed: $error");
  // Try loading a new ad
  _loadNewAd();
}

🔍 Troubleshooting

Problem: Ads not showing

Checklist:

  1. ✅ Is SDK initialized? (Check onSuccess callback)
  2. ✅ Is your App ID correct?
  3. ✅ Do you have internet connection?
  4. ✅ Are you testing on a real device?
  5. ✅ Is your app properly configured in Yodo1 dashboard?
  6. ✅ Are you calling the ad methods after SDK initialization?

Problem: Ads showing but callbacks not working

Solution:

  • Make sure you're setting callbacks before calling loadAndShow* methods
  • Check that callbacks are not null
  • Verify method channel names match

Problem: App crashes when showing ads

Solution:

  • Check platform setup (Android/iOS configuration)
  • Verify minimum SDK versions
  • Check for null pointer exceptions in callbacks
  • Review error logs

Problem: Privacy dialog not showing

Solution:

  • Ensure showPrivacyDialog: true in initialization
  • Check platform-specific privacy settings
  • Verify Info.plist (iOS) or AndroidManifest.xml (Android)

📚 API Reference

Yodosdk Class

initSdk()

Initializes the Yodo SDK.

Parameters:

  • appId (String, required) - Your Yodo App ID
  • preLoadAds (bool, default: false) - Preload ads for better performance
  • showPrivacyDialog (bool, default: true) - Show privacy dialog
  • coppa (bool, default: false) - COPPA compliance
  • gdpr (bool, default: true) - GDPR compliance
  • ccpa (bool, default: false) - CCPA compliance
  • initAdCallback (InitAdCallback, required) - Initialization callbacks

loadAndShowInter()

Loads and shows an interstitial ad.

Parameters:

  • fullScreenAdCallbacks (FullScreenAdCallbacks, required) - Ad event callbacks
  • placementId (String?, optional) - Custom placement ID

loadAndShowReward()

Loads and shows a rewarded ad.

Parameters:

  • rewardAdCallbacks (RewardAdCallbacks, required) - Ad event callbacks
  • placementId (String?, optional) - Custom placement ID

loadAndShowRewardInter()

Loads and shows a rewarded interstitial ad.

Parameters:

  • rewardAdCallbacks (RewardAdCallbacks, required) - Ad event callbacks
  • placementId (String?, optional) - Custom placement ID

loadAndShowAppOpen()

Loads and shows an app open ad.

Parameters:

  • fullScreenAdCallbacks (FullScreenAdCallbacks, required) - Ad event callbacks
  • placementId (String?, optional) - Custom placement ID

getBanner()

Creates a banner ad widget.

Parameters:

  • bannerAdCallback (BannerAdCallback, required) - Ad event callbacks
  • size (BannerSize, default: BannerSize.largeBanner) - Banner size

Returns: Widget

getNative()

Creates a native ad widget.

Parameters:

  • nativeAdCallback (NativeAdCallback, required) - Ad event callbacks
  • size (NativeSize, default: NativeSize.nativeSmall) - Native ad size

Returns: Widget

showPrivacyDialog()

Shows the privacy dialog.

Callback Classes

InitAdCallback

  • onSuccess() - Called when SDK initializes successfully
  • onError(String? error) - Called when initialization fails

FullScreenAdCallbacks

  • onLoad(String? adId) - Called when ad loads
  • onAdLoadFail(String? error) - Called when ad fails to load
  • onAdOpen(String? adId) - Called when ad opens
  • onAdOpenFail(String? error) - Called when ad fails to open
  • onClose(String? adId) - Called when ad closes

RewardAdCallbacks

  • onLoad(dynamic adId) - Called when ad loads
  • onAdLoadFail(dynamic error) - Called when ad fails to load
  • onAdOpen(dynamic adId) - Called when ad opens
  • onAdOpenFail(dynamic error) - Called when ad fails to open
  • onClose(dynamic adId) - Called when ad closes
  • onRewardEarned(dynamic adId) - Called when user earns reward

BannerAdCallback

  • onLoad() - Called when banner loads
  • onLoadFailed(String errorMessage) - Called when banner fails to load
  • onOpen() - Called when banner is clicked
  • onOpenFail(String error) - Called when banner click fails
  • onClosed() - Called when banner is closed

NativeAdCallback

  • onLoad() - Called when native ad loads
  • onLoadFailed(String errorMessage) - Called when native ad fails to load
  • onClosed() - Called when native ad is closed

📞 Support

📄 License

See LICENSE file for details.

🙏 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.


Made with ❤️ for Flutter developers