magic_ad_sdk 0.0.3 copy "magic_ad_sdk: ^0.0.3" to clipboard
magic_ad_sdk: ^0.0.3 copied to clipboard

Magic Ads SDK Flutter plugin for Android and iOS.

magic_ad_sdk #

English | 简体中文

MagicAdSDK Flutter plugin for Android and iOS.

This package provides a Flutter MethodChannel bridge for MagicAdSDK, including SDK initialization, ad loading, ad display, PlatformView-based ad rendering, event streams, and object lifecycle management.

Features #

  • SDK initialization and logging configuration
  • Splash ads
  • Rewarded video ads
  • Interstitial ads
  • Banner ads with Flutter PlatformView embedding
  • Feed ads with Flutter PlatformView embedding
  • Self-render feed ads with Flutter PlatformView embedding
  • Ad lifecycle events through broadcast streams
  • Per-ad-object lifecycle management with objectID

Requirements #

Flutter and Dart:

  • Flutter: >=3.10.0
  • Dart SDK: >=3.0.0 <4.0.0

Android:

  • minSdk: 21
  • compileSdk: 34
  • Java: 11
  • Kotlin Gradle Plugin: 2.1.0
  • Android Gradle Plugin: 8.9.1
  • MagicAdSDK Android: com.magic.ad.sdk:magicadsdk:0.0.63

iOS:

  • iOS deployment target: 13.0
  • Swift: 5.0
  • MagicAdSDK iOS: MagicAdSDK 0.0.63

Installation #

Add the package to your Flutter app:

dependencies:
  magic_ad_sdk: ^0.0.1

Then import the unified API entry:

import 'package:magic_ad_sdk/magic_index.dart';

Android Setup #

MagicAdSDK is resolved from the Magic Maven repository. Add the repository to your host Android project.

For newer Flutter Android templates, configure repositories in android/settings.gradle or the root Gradle file used by your app:

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        maven {
            url "https://mv.magicacid.cn/repository/maven-public/"
            allowInsecureProtocol = true
        }
        google()
        mavenCentral()
    }
}

If your app needs to load HTTP ad assets, configure Android cleartext traffic for the required asset domains in your host app. One common approach is to add a network_security_config.xml file and reference it from AndroidManifest.xml:

<application
    android:networkSecurityConfig="@xml/network_security_config">
</application>

iOS Setup #

The plugin podspec depends on MagicAdSDK 0.0.63, which is integrated through CocoaPods when your Flutter app installs pods.

Set the minimum deployment target to iOS 13.0 or later in your app's ios/Podfile:

platform :ios, '13.0'

Then install pods:

cd ios
pod install

If your app uses IDFA or location-based capabilities, request the required permissions in the host app and pass the resulting configuration to MagicAdSDK according to your app's privacy and compliance requirements.

Initialize SDK #

Register event streams before initialization if you need to observe init status:

final initSubscription =
    MagicListenerManager.initEventHandler.listen((event) {
  if (event.initStatus == MagicInitStatus.initSuccess) {
    debugPrint('MagicAdSDK initialized');
  } else if (event.initStatus == MagicInitStatus.initFailed) {
    debugPrint('MagicAdSDK init failed: ${event.errorMessage}');
  }
});

await MagicInitManger.initMagicSDK(appId: 'your_app_id');
await MagicInitManger.setLogEnabled(logEnabled: true);

Ad Object Lifecycle #

Each loadXxx call returns an independent ad object with its own objectID. Multiple ads can be loaded for the same placement without overwriting each other.

Always destroy ad objects when they are no longer needed:

await adObject.destroy();

Recommended lifecycle rules:

  • Store the returned ad object while the page owns it.
  • Filter stream events by event.adObject?.objectID.
  • Use getPrice() after the ad has loaded if you need the native bid price value.
  • Call destroy() in dispose, on route exit, or before reusing an ad slot.
  • If a page exits while loadXxx is still awaiting, destroy the returned object immediately once the future completes.
  • When an ad sends a closed event, clear the reference held by your page.

Splash Ads #

MagicSplashAdObject? splashAd;

final splashSubscription =
    MagicListenerManager.splashEventHandler.listen((event) {
  if (event.adObject?.objectID != splashAd?.objectID) return;

  if (event.isClosed) {
    splashAd = null;
  }
});

splashAd = await MagicSplashManager.loadSplash(
  placementID: 'your_placement_id',
);

if (await splashAd?.ready() == true) {
  await splashAd?.show();
}

Rewarded Video Ads #

MagicRewardedAdObject? rewardedAd;

final rewardedSubscription =
    MagicListenerManager.rewardedVideoEventHandler.listen((event) {
  if (event.adObject?.objectID != rewardedAd?.objectID) return;

  if (event.rewardedVideoStatus == MagicRewardedVideoStatus.rewarded) {
    debugPrint('Reward granted');
  }

  if (event.isClosed) {
    rewardedAd = null;
  }
});

rewardedAd = await MagicRewardedManager.loadRewardedVideo(
  placementID: 'your_placement_id',
);

if (await rewardedAd?.ready() == true) {
  await rewardedAd?.show();
}

Interstitial Ads #

MagicInterstitialAdObject? interstitialAd;

final interstitialSubscription =
    MagicListenerManager.interstitialEventHandler.listen((event) {
  if (event.adObject?.objectID != interstitialAd?.objectID) return;

  if (event.isClosed) {
    interstitialAd = null;
  }
});

interstitialAd = await MagicInterstitialManager.loadInterstitialAd(
  placementID: 'your_placement_id',
);

if (await interstitialAd?.ready() == true) {
  await interstitialAd?.show();
}

Load a banner ad and embed it with MagicBannerAdView:

MagicBannerAdObject? bannerAd;

bannerAd = await MagicBannerManager.loadBannerAd(
  placementID: 'your_placement_id',
  width: 320,
  height: 50,
);
if (bannerAd != null)
  SizedBox(
    width: 320,
    height: 50,
    child: MagicBannerAdView(adObject: bannerAd!),
  )

Destroy the banner when it leaves the page:

await bannerAd?.destroy();
bannerAd = null;

Feed Ads #

Load a feed ad and embed it with MagicFeedAdView:

MagicFeedAdObject? feedAd;

feedAd = await MagicFeedManager.loadFeedAd(
  placementID: 'your_placement_id',
  width: MediaQuery.sizeOf(context).width,
  height: 0,
);
if (feedAd != null)
  MagicFeedAdView(adObject: feedAd!)

You can query and control video state when supported by the native ad:

final isVideo = await feedAd?.isVideo();
final isPlaying = await feedAd?.isPlaying();
await feedAd?.pauseVideo();
await feedAd?.resumeVideo();

Self-render Feed Ads #

Load a self-render feed ad and embed it with MagicSelfRenderFeedAdView:

MagicSelfRenderFeedAdObject? selfRenderFeedAd;

selfRenderFeedAd = await MagicFeedManager.loadSelfRenderFeedAd(
  placementID: 'your_placement_id',
  width: MediaQuery.sizeOf(context).width,
  height: 0,
);
if (selfRenderFeedAd != null)
  MagicSelfRenderFeedAdView(adObject: selfRenderFeedAd!)

Self-render feed video events are emitted through selfRenderFeedEventHandler.

Error Handling #

Native loading failures are reported in two ways:

  • The Future returned by loadXxx throws a PlatformException.
  • The corresponding event stream emits a loadFailed event.
import 'package:flutter/services.dart';

try {
  final ad = await MagicSplashManager.loadSplash(
    placementID: 'your_placement_id',
  );
  await ad?.show();
} on PlatformException catch (error) {
  debugPrint('Load failed: ${error.code} ${error.message}');
}

Stream events also include fields such as errorCode, errorMessage, rawMap, and adObject.

Event Streams #

Available event streams:

  • MagicListenerManager.initEventHandler
  • MagicListenerManager.splashEventHandler
  • MagicListenerManager.rewardedVideoEventHandler
  • MagicListenerManager.interstitialEventHandler
  • MagicListenerManager.bannerEventHandler
  • MagicListenerManager.feedEventHandler
  • MagicListenerManager.selfRenderFeedEventHandler

Because these streams are broadcast streams, multiple pages can receive the same type of event. Always filter events by the ad object's objectID when a page owns a specific ad.

final subscription =
    MagicListenerManager.bannerEventHandler.listen((event) {
  if (event.adObject?.objectID != bannerAd?.objectID) return;
  debugPrint('Banner event: ${event.bannerStatus}');
});

Cancel stream subscriptions when the owning object or page is disposed:

await subscription.cancel();

Extra Parameters #

Each ad loading API accepts an optional extraMap. Key helper methods are provided by each manager:

final ad = await MagicRewardedManager.loadRewardedVideo(
  placementID: 'your_placement_id',
  extraMap: {
    MagicRewardedManager.videoMuteKey(): true,
    MagicRewardedManager.bidFloorKey(): 10,
  },
);

Common helper methods include:

  • MagicSplashManager.bidFloorKey()
  • MagicSplashManager.videoMuteKey()
  • MagicRewardedManager.bidFloorKey()
  • MagicRewardedManager.videoMuteKey()
  • MagicInterstitialManager.bidFloorKey()
  • MagicInterstitialManager.videoMuteKey()
  • MagicBannerManager.bidFloorKey()
  • MagicBannerManager.videoMuteKey()
  • MagicFeedManager.bidFloorKey()
  • MagicFeedManager.autoPlayKey()
  • MagicFeedManager.videoMuteKey()
  • MagicCommon.getShowCustomExtKey()

API Overview #

Initialization:

  • MagicInitManger.initMagicSDK({required appId})
  • MagicInitManger.getSDKVersion()
  • MagicInitManger.setLogEnabled({logEnabled})

Splash:

  • MagicSplashManager.loadSplash({placementID, extraMap})
  • MagicSplashAdObject.ready()
  • MagicSplashAdObject.getPrice()
  • MagicSplashAdObject.show()
  • MagicSplashAdObject.destroy()

Rewarded video:

  • MagicRewardedManager.loadRewardedVideo({placementID, extraMap})
  • MagicRewardedAdObject.ready()
  • MagicRewardedAdObject.getPrice()
  • MagicRewardedAdObject.show()
  • MagicRewardedAdObject.destroy()

Interstitial:

  • MagicInterstitialManager.loadInterstitialAd({placementID, extraMap})
  • MagicInterstitialAdObject.ready()
  • MagicInterstitialAdObject.getPrice()
  • MagicInterstitialAdObject.show()
  • MagicInterstitialAdObject.destroy()

Banner:

  • MagicBannerManager.loadBannerAd({placementID, width, height, extraMap})
  • MagicBannerAdView(adObject: bannerAd)
  • MagicBannerAdObject.realHeight()
  • MagicBannerAdObject.getPrice()
  • MagicBannerAdObject.destroy()

Feed:

  • MagicFeedManager.loadFeedAd({placementID, width, height, extraMap})
  • MagicFeedAdView(adObject: feedAd)
  • MagicFeedAdObject.realHeight()
  • MagicFeedAdObject.isVideo()
  • MagicFeedAdObject.isPlaying()
  • MagicFeedAdObject.pauseVideo()
  • MagicFeedAdObject.resumeVideo()
  • MagicFeedAdObject.getPrice()
  • MagicFeedAdObject.destroy()

Self-render feed:

  • MagicFeedManager.loadSelfRenderFeedAd({placementID, width, height, extraMap})
  • MagicSelfRenderFeedAdView(adObject: selfRenderFeedAd)
  • MagicSelfRenderFeedAdObject.realHeight()
  • MagicSelfRenderFeedAdObject.isVideo()
  • MagicSelfRenderFeedAdObject.isPlaying()
  • MagicSelfRenderFeedAdObject.pauseVideo()
  • MagicSelfRenderFeedAdObject.resumeVideo()
  • MagicSelfRenderFeedAdObject.getPrice()
  • MagicSelfRenderFeedAdObject.destroy()

Example App #

The example/ directory contains a Flutter sample app showing SDK initialization, ad loading, PlatformView embedding, event handling, and object cleanup.

Run it with:

cd example
flutter pub get
flutter run

License #

This package is released under the MIT License. See LICENSE for details.

0
likes
130
points
163
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Magic Ads SDK Flutter plugin for Android and iOS.

Topics

#ads #advertising #flutter-plugin

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on magic_ad_sdk

Packages that implement magic_ad_sdk