npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

capacitor-levelplay

v0.3.0

Published

Capacitor 7 and 8 plugin for Unity LevelPlay (ironSource) ads on Android and iOS: rewarded, interstitial, banner and native ads, impression-level revenue, segments, ad-unit API, Swift Package Manager first, ATT and GDPR / CCPA / COPPA consent.

Readme

capacitor-levelplay

npm version license: MIT Capacitor 7 | 8 LevelPlay SDK 9.6.1

Capacitor 7 and 8 plugin for Unity LevelPlay (formerly ironSource) mediation: rewarded, interstitial, banner and native ads on Android and iOS, plus impression-level revenue data, built on LevelPlay's current ad-unit API (LevelPlay.init, LevelPlayRewardedAd / LPMRewardedAd, LevelPlayInterstitialAd / LPMInterstitialAd, LevelPlayBannerAdView / LPMBannerAdView, LevelPlayNativeAd).

import { LevelPlay } from 'capacitor-levelplay';

await LevelPlay.initialize({ appKey: 'your-app-key' });
await LevelPlay.loadRewarded({ adUnitId: 'your-rewarded-ad-unit' });
// ...
const result = await LevelPlay.showRewarded({ adUnitId: 'your-rewarded-ad-unit' });
if (result.rewarded) grantCoins(result.reward!.amount);

Contents

Features

  • Rewarded and interstitial ads with LevelPlay's ad-unit API (SDK 9.x). One native ad object per ad unit id, so several rewarded or interstitial ad units can be used side by side.
  • Promise-based show: showRewarded / showInterstitial resolve after the ad closes with { shown, rewarded, reward?, error?, adInfo? }. They never reject because an ad was not ready, and the plugin handles networks that deliver the reward after the close callback.
  • Swift Package Manager first on iOS: the plugin's Package.swift depends on Unity's official LevelPlay-Swift-Package, so npx cap sync on an SPM project really pulls the SDK. A podspec (IronSourceSDK) is included for CocoaPods projects.
  • App Tracking Transparency helper on iOS (requestTrackingAuthorization, getTrackingAuthorizationStatus).
  • GDPR, CCPA and COPPA signals through LevelPlay's privacy settings API, settable before init.
  • Integration Test Suite and integration validation (launchTestSuite, validateIntegration) for checking adapters during development.
  • Typed events (loaded, loadFailed, displayed, displayFailed, clicked, closed, rewarded) with ad info including impression revenue.
  • Banners (0.3.0): standard sizes, adaptive (follows the safe-area width and rotation), and custom sizes; placed at the top, bottom or centre with offsets, inside the safe area, in a pass-through overlay above the WebView (touches beside a banner reach the page). Several banners at once, addressed by bannerId.
  • Native ads (0.3.0): the plugin's small and medium templates, styled from JS (colours, corner radius, fonts) and placed over any rectangle of the page, typically a placeholder element's getBoundingClientRect().
  • Impression-level revenue (0.3.0): impressionData for rewarded, interstitial, banner and native ads, queued (up to 100) until the first listener so early impressions are not lost; adInfoChanged for full-screen ads.
  • Segments, dynamic user id, placement capping and rewards (0.3.0): setSegment, setDynamicUserId, isPlacementCapped, getReward.
  • Capabilities (0.3.0): getCapabilities() tells what the current platform supports.
  • Demo ids (LEVELPLAY_DEMO) from Unity's public sample apps for test ads during development.
  • Web stub: on the web nothing is ever ready and shows resolve { shown: false }, so the same game code runs in a browser.

Compatibility

| | Version | |---|---| | Capacitor | 7 and 8 (@capacitor/core >= 7.0.0) | | Unity LevelPlay SDK | 9.6.1 (Android com.unity3d.ads-mediation:mediation-sdk:9.6.1; iOS LevelPlay-Swift-Package 9.6.1 up to < 10, or the IronSourceSDK ~> 9.6.1 pod) | | iOS | 14.0+ deployment target (Capacitor 7 default; Capacitor 8 apps use 15.0) | | Xcode | 16+ for Capacitor 7, 26+ for Capacitor 8; tested with Xcode 27 (which needs an app target of iOS 15.0+) | | Android | minSdk 23+, compileSdk / targetSdk 35 (Capacitor 7) or 36 (Capacitor 8), taken from the app's variables.gradle | | Java | JDK 21 for Gradle builds | | Node.js | 20+ (Capacitor 7 CLI), 22+ (Capacitor 8 CLI) |

| Plugin | Capacitor | LevelPlay SDK | |---|---|---| | 0.3.x | 7, 8 | 9.6.1 | | 0.2.x | 8 | 9.6.1 | | 0.1.x | 8 | 9.6.1 |

Install

npm install capacitor-levelplay
npx cap sync
bun add capacitor-levelplay && bunx cap sync
yarn add capacitor-levelplay && yarn cap sync
pnpm add capacitor-levelplay && pnpm cap sync

iOS setup

Swift Package Manager (default)

Capacitor 8 projects (and Capacitor 7 projects created with --packagemanager SPM) need nothing extra: npx cap sync adds the plugin to CapApp-SPM/Package.swift and Xcode resolves the LevelPlay package (a binary xcframework, roughly 27 MB) on the next build.

CocoaPods (alternative)

CocoaPods projects get the CapacitorLevelplay pod from npx cap sync; it depends on Capacitor and IronSourceSDK ~> 9.6.1. Run pod install (or npx cap sync ios) as usual. Mediation adapters are then added as pods (IronSource<Network>Adapter) in the app's Podfile.

-ObjC linker flag

LevelPlay requires it: App target > Build Settings > Linking > Other Linker Flags > add -ObjC.

Info.plist

<!-- App Tracking Transparency prompt text (requestTrackingAuthorization). -->
<key>NSUserTrackingUsageDescription</key>
<string>Your data will be used to deliver ads that are more relevant to you.</string>

<!-- SKAdNetwork ids: LevelPlay's own id plus the ids of every network you mediate (see below). -->
<key>SKAdNetworkItems</key>
<array>
  <dict>
    <key>SKAdNetworkIdentifier</key>
    <string>su67r6k2v3.skadnetwork</string>
  </dict>
  <!-- ... -->
</array>

<!-- Recommended: copies of winning SKAdNetwork install-validation postbacks. -->
<key>NSAdvertisingAttributionReportEndpoint</key>
<string>https://postbacks-is.com/</string>

<!-- LevelPlay's integration guide asks for arbitrary loads (some ad creatives are served over http). -->
<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

Generating SKAdNetworkItems. su67r6k2v3.skadnetwork is LevelPlay's (ironSource Ads) id. Every mediated network needs its own ids as well. Use Unity's SKAdNetwork ID manager to export the combined list for the networks you enable, or merge each network's official list yourself (for example Unity Ads publishes https://skan.mz.unity3d.com/v3/partner/skadnetworks.plist.json). A small script that downloads the lists, extracts every xxxxxxxxxx.skadnetwork id, de-duplicates them and rewrites the SKAdNetworkItems array keeps this repeatable; re-run it whenever you add a network and before each release. Some lists also carry AdAttributionKit ids (.adattributionkit), which go into the AdNetworkIdentifiers array.

Full checklist: Unity's iOS SDK integration guide.

Android setup

Nothing beyond npx cap sync for most apps:

  • Repositories: the SDK and all LevelPlay adapters are on Maven Central. Capacitor's default android/build.gradle already lists google() and mavenCentral(); keep both.
  • Permissions: the plugin's manifest adds com.google.android.gms.permission.AD_ID (required for the advertising id on Android 13+). The SDK's own manifest brings INTERNET, ACCESS_NETWORK_STATE, its activities and providers. A child-directed app can strip AD_ID from its manifest with tools:node="remove".
  • Dependencies: the plugin module declares mediation-sdk plus the Play services ads-identifier, appset and basement artifacts the LevelPlay guide asks for.
  • ProGuard / R8: the core keep rules ship as consumer rules. If you minify, add the per-network rules from Unity's Android SDK integration guide for each adapter you add.

Optional: pin a different 9.x SDK from the app's android/variables.gradle:

ext {
    levelPlayVersion = '9.6.1'
}

Gradle in Capacitor 7 and 8 projects needs JDK 21 (see Troubleshooting).

Quick start

import { Capacitor } from '@capacitor/core';
import { LevelPlay, LEVELPLAY_DEMO } from 'capacitor-levelplay';

// Unity's public demo ids serve test ads. Replace them with your own before release.
const ids = Capacitor.getPlatform() === 'ios' ? LEVELPLAY_DEMO.ios : LEVELPLAY_DEMO.android;

export async function startAds(): Promise<void> {
  await LevelPlay.requestTrackingAuthorization(); // iOS ATT prompt; resolves 'unavailable' elsewhere
  await LevelPlay.initialize({
    appKey: ids.appKey,
    consent: { gdprConsent: false }, // until your CMP says otherwise, see "Privacy and consent"
  });
  await LevelPlay.loadRewarded({ adUnitId: ids.rewarded });
  await LevelPlay.loadInterstitial({ adUnitId: ids.interstitial });
}

export async function watchVideoForCoins(): Promise<number> {
  const result = await LevelPlay.showRewarded({ adUnitId: ids.rewarded });
  void LevelPlay.loadRewarded({ adUnitId: ids.rewarded }); // preload the next one
  return result.rewarded ? (result.reward?.amount ?? 0) : 0;
}

Usage guide

Initialise with consent

Initialise once, as early as is sensible, after consent is known (and on iOS after the ATT prompt). Ads can only be loaded after initialize resolves.

const { status } = await LevelPlay.requestTrackingAuthorization(); // iOS only, see Privacy and consent

const { sdkVersion } = await LevelPlay.initialize({
  appKey: ids.appKey,
  userId: playerId, // optional: needed for server-to-server reward callbacks
  consent: {
    gdprConsent: cmpSaysYes, // EEA / UK / CH users: false until a CMP collected consent
    ccpaDoNotSell: false, // true if a US user opted out of sale / sharing
    coppa: false, // true for child-directed treatment
  },
});

initialize rejects with the SDK's init error (code, message); you can call it again later. Calling it after a successful init resolves immediately, and concurrent calls share one init.

Rewarded ads

const REWARDED = ids.rewarded;

await LevelPlay.loadRewarded({ adUnitId: REWARDED });

// When the player taps "Watch a video":
const { ready } = await LevelPlay.isReady({ format: 'rewarded', adUnitId: REWARDED });
if (!ready) {
  showToast('No video available right now');
} else {
  const result = await LevelPlay.showRewarded({ adUnitId: REWARDED, placementName: 'DoubleCoins' });
  if (result.rewarded && result.reward) {
    grant(result.reward.name, result.reward.amount);
  } else if (result.error) {
    console.warn('rewarded not shown', result.error.code, result.error.message);
  }
  await LevelPlay.loadRewarded({ adUnitId: REWARDED }); // always load the next one
}
  • The show promise resolves after the ad closes (or failed to display).
  • Grant the reward only when rewarded is true. The reward and close callbacks can arrive in either order on some networks; the plugin waits up to 1 second after the close for a late reward before resolving.
  • When the ad is not ready, the promise resolves { shown: false, rewarded: false, error: { code: -1, message: 'Ad not ready' } }.
  • placementName is optional and refers to a placement configured in the LevelPlay dashboard (capping, pacing, reward).
  • For server-side rewards, pass userId to initialize and configure server-to-server callbacks in the dashboard.

Interstitial ads

await LevelPlay.loadInterstitial({ adUnitId: ids.interstitial });

// At a natural break, for example between levels:
const result = await LevelPlay.showInterstitial({ adUnitId: ids.interstitial });
// result.shown tells you whether it was displayed; game flow continues after the close.
void LevelPlay.loadInterstitial({ adUnitId: ids.interstitial });

Listening to events

Load results arrive only as events, so listen for loaded / loadFailed if you want to drive UI or retry logic.

import type { PluginListenerHandle } from '@capacitor/core';

const handles: PluginListenerHandle[] = [
  await LevelPlay.addListener('loaded', (e) => console.log('loaded', e.format, e.adUnitId, e.adInfo?.adNetwork)),
  await LevelPlay.addListener('loadFailed', (e) => {
    console.warn('load failed', e.format, e.error.code, e.error.message);
    setTimeout(() => {
      void (e.format === 'rewarded'
        ? LevelPlay.loadRewarded({ adUnitId: e.adUnitId })
        : LevelPlay.loadInterstitial({ adUnitId: e.adUnitId }));
    }, 30_000); // retry later; use an increasing backoff in production
  }),
  await LevelPlay.addListener('displayed', (e) => trackImpression(e.adInfo?.revenue, e.adInfo?.adNetwork)),
  await LevelPlay.addListener('rewarded', (e) => console.log('reward', e.reward.name, e.reward.amount)),
  await LevelPlay.addListener('closed', (e) => resumeAudio()),
];

// later
await Promise.all(handles.map((h) => h.remove()));
// or: await LevelPlay.removeAllListeners();

Every event carries { format: 'rewarded' | 'interstitial', adUnitId, adInfo? }, plus error on loadFailed / displayFailed and reward on rewarded.

Checking readiness

isReady({ format, adUnitId }) returns the native isAdReady() for that ad unit. It is false for an ad unit that was never loaded. Use it to enable or disable a "watch video" button.

Banners

A banner is created hidden, then loaded and shown. createBanner resolves the banner's size and on-screen frame (CSS px, relative to the WebView viewport), so the page can leave room for it.

const banner = await LevelPlay.createBanner({
  adUnitId: ids.banner,
  bannerId: 'main', // optional; defaults to adUnitId
  size: 'ADAPTIVE', // BANNER 320x50, LARGE 320x90, MEDIUM_RECTANGLE 300x250, LEADERBOARD 728x90, ADAPTIVE, CUSTOM
  position: 'bottom', // 'top' | 'bottom' | 'center'
  offsetY: 0, // CSS px, away from the edge
  respectSafeArea: true, // default: stays clear of notches, status bar, navigation bar and home indicator
});
document.body.style.paddingBottom = `${banner.frame.height}px`;

await LevelPlay.addListener('bannerLoaded', (e) => console.log('banner', e.bannerId, e.frame));
await LevelPlay.addListener('bannerLoadFailed', (e) => console.warn('banner failed', e.error.code));
await LevelPlay.loadBanner({ bannerId: 'main' }); // once per banner object; the SDK refreshes and retries by itself
await LevelPlay.showBanner({ bannerId: 'main' });

await LevelPlay.setBannerLayout({ bannerId: 'main', position: 'top' }); // move it
await LevelPlay.hideBanner({ bannerId: 'main' }); // hidden banners pause auto refresh
await LevelPlay.destroyBanner({ bannerId: 'main' });
  • ADAPTIVE uses the safe-area width (or adaptiveWidth in CSS px) and is recreated and reloaded automatically when that width changes, for example on rotation, keeping its id, position and visibility.
  • CUSTOM takes customSize: { width, height } in CSS px.
  • Banner events: bannerLoaded, bannerLoadFailed, bannerDisplayed, bannerDisplayFailed, bannerClicked, bannerExpanded, bannerCollapsed, bannerLeftApplication, all with { bannerId, adUnitId, adInfo?, frame? }.

| Top and bottom (Android) | Rotated, adaptive (Android) | |---|---| | Adaptive banners at the top and bottom | Adaptive banner recreated after rotation |

Native ads

Native ads are drawn by the plugin's templates (small: a row at least 90 px tall, no media; medium: with a media view, about 300 x 350) and placed over a rectangle of the page, usually a placeholder element. Check getCapabilities() first.

const caps = await LevelPlay.getCapabilities();
if (caps.nativeAd && caps.nativeAdTemplates.includes('small')) {
  const slot = document.getElementById('native-slot')!; // e.g. a 90 px tall div

  await LevelPlay.addListener('nativeAdLoaded', async (e) => {
    const r = slot.getBoundingClientRect();
    await LevelPlay.showNativeAd({ nativeAdId: e.nativeAdId, rect: { x: r.left, y: r.top, width: r.width, height: r.height } });
  });
  await LevelPlay.addListener('nativeAdLoadFailed', (e) => console.warn('native failed', e.error.code));

  await LevelPlay.loadNativeAd({
    nativeAdId: 'feed-1',
    template: 'small',
    placementName: 'Feed', // optional
    style: {
      backgroundColor: '#ffffff',
      titleColor: '#111111',
      bodyColor: '#555555',
      callToActionBackgroundColor: '#2f6fed',
      callToActionTextColor: '#ffffff',
      cornerRadius: 8,
      titleFont: { family: 'fonts/Inter-SemiBold.ttf', size: 15 }, // a web asset path or a system family
      bodyFont: { size: 13 },
      callToActionFont: { family: 'Helvetica', size: 14 },
    },
  });
}

// keep it on the placeholder while the page scrolls or resizes
await LevelPlay.setNativeAdRect({ nativeAdId: 'feed-1', rect: { x: 16, y: 420, width: 343, height: 90 } });
await LevelPlay.hideNativeAd({ nativeAdId: 'feed-1' });
await LevelPlay.destroyNativeAd({ nativeAdId: 'feed-1' });

Style options (NativeAdTemplateStyle): backgroundColor, titleColor, bodyColor, callToActionBackgroundColor, callToActionTextColor (#RRGGBB or #RRGGBBAA), cornerRadius (CSS px), and titleFont, bodyFont, callToActionFont ({ family?, size? }; a .ttf / .otf path is read from the app's web assets, anything else is a system font family; a missing font falls back to the system font). The template texts "Ad" and "Open" can be localised with the app resources levelplay_native_ad_badge and levelplay_native_ad_cta_fallback (Android strings.xml, iOS Localizable.strings).

Native events: nativeAdLoaded, nativeAdLoadFailed, nativeAdImpression, nativeAdClicked, all with { nativeAdId, placementName?, adInfo? }.

Impression-level revenue

await LevelPlay.addListener('impressionData', (d) => {
  // d.adFormat as the SDK reports it ('Rewarded Video', 'Interstitial', 'Banner', 'nativead' ...); d.revenue in USD
  analytics.logAdImpression({ network: d.adNetwork, format: d.adFormat, revenue: d.revenue ?? 0, currency: 'USD' });
});

Impressions that happen before the first listener (for example a banner shown during app start) are queued, up to 100, and delivered in order when the first impressionData listener is added. d.allData carries every raw field of the SDK's impression object. adInfoChanged fires when the ad info of a loaded rewarded or interstitial ad changes.

Segments, user id, placements

await LevelPlay.setSegment({ segmentName: 'whales', level: 12, isPaying: true, iapTotal: 49.99, customParameters: { cohort: 'b' } });
await LevelPlay.setDynamicUserId({ userId: 'player-123' }); // { valid } ; used for server-to-server rewards

const { capped } = await LevelPlay.isPlacementCapped({ format: 'rewarded', placementName: 'Shop' });
const reward = await LevelPlay.getReward({ adUnitId: ids.rewarded, placementName: 'Shop' }); // { name, amount }
await LevelPlay.showRewarded({ adUnitId: ids.rewarded, placementName: 'Shop' });

setSegment takes at most 5 custom parameters, keys and values 1-32 letters and digits (SDK limits); invalid input rejects with INVALID_ARGUMENT instead of being dropped silently by the SDK.

Error codes

Calls reject with a code: INVALID_ARGUMENT, NOT_INITIALIZED (banner / native before initialize()), ALREADY_EXISTS (banner id in use), NOT_FOUND (unknown banner or native id), NOT_LOADED (showNativeAd before nativeAdLoaded), UNSUPPORTED, NO_ACTIVITY (Android) / NO_VIEW_CONTROLLER (iOS), UNIMPLEMENTED (web). hideBanner and the destroy* calls resolve for unknown ids. Ad load and show errors arrive in events as { code, message } with the SDK's code (509 is "no fill").

Integration Test Suite

The Integration Test Suite shows every configured network, its adapter status and lets you request test ads per network.

await LevelPlay.initialize({ appKey: ids.appKey, testSuite: true }); // sets is_test_suite=enable before init
await LevelPlay.launchTestSuite();

Development builds only. Unity recommends not calling other LevelPlay APIs before launching the suite, and the suite supports portrait orientation only.

Validate the integration

await LevelPlay.validateIntegration();

Writes LevelPlay's integration helper report to the native log: the Xcode console on iOS, logcat tag IntegrationHelper on Android (adb logcat | grep IntegrationHelper). Each network is listed with its adapter and SDK version and VERIFIED when everything is in place. Remove the call from release builds.

Meta data

Network-specific and SDK flags go through setMetaData before init, for example:

await LevelPlay.setMetaData({ key: 'is_deviceid_optout', value: 'true' });

Demo ids

LEVELPLAY_DEMO holds the public app keys and ad unit ids from Unity's official sample apps (Mediation-Demo-Apps). They serve test ads; never ship them.

| Platform | App key | Rewarded | Interstitial | Banner | |---|---|---|---|---| | Android | 25b63cf85 | syz3d8ekts22q0or | h3xw38h9214adgxo | 4fpetq4lhe5lsw3e | | iOS | 8545d445 | qwouvdrkuwivay5q | wmgt0712uuux8ju4 | iep3rxsyp9na3rw8 |

The sample apps have no native ad unit; native ads load with the app key's default placement.

Web

LevelPlay has no web SDK. On the web initialize and launchTestSuite reject as unimplemented, isReady is always false and shows resolve { shown: false, rewarded: false, error: { code: -1, ... } }. getCapabilities() reports nothing supported; createBanner, showBanner, setBannerLayout, loadNativeAd and showNativeAd reject as unimplemented; setSegment, loadBanner, hide and destroy calls are no-ops; setDynamicUserId resolves { valid: false }, isPlacementCapped { capped: false } and getReward { name: '', amount: 0 }.

Example app

example-app/ is a minimal Capacitor 8 app (HTML + TypeScript) that uses the plugin from this repository with the demo ids: initialize, rewarded, interstitial, banner top / bottom / hide / destroy, native small / medium, segment and an impression log. See its README for the steps.

Mediation adapters

The plugin brings the LevelPlay SDK (which includes ironSource Ads). Every other network is an adapter plus that network's SDK, added to your app, not to the plugin. Pick versions from Unity's adapter tables (Android, iOS) and take each adapter together with the network SDK version it was built for (the adapter changelog says "Supporting SDK version ..."). Then enable the network in the LevelPlay dashboard.

Android (Gradle)

Adapters live on Maven Central under com.unity3d.ads-mediation:<network>-adapter:<version>. Add each adapter and the network SDK to android/app/build.gradle:

dependencies {
    // Unity Ads
    implementation 'com.unity3d.ads-mediation:unityads-adapter:<adapter version>'
    implementation 'com.unity3d.ads:unity-ads:<sdk version>'
    // Liftoff Monetize (Vungle)
    implementation 'com.unity3d.ads-mediation:vungle-adapter:<adapter version>'
    implementation 'com.vungle:vungle-ads:<sdk version>'
}

List the network SDK explicitly: the adapter artifacts do not pull it in. Some networks need more (Google AdMob, for example, needs its com.google.android.gms.ads.APPLICATION_ID meta-data in AndroidManifest.xml, or the app crashes at launch); check the network's page in Unity's docs.

iOS (Swift Package Manager)

Unity publishes official adapter packages on GitHub as https://github.com/ironsource-mobile/LevelPlay-<Network>-Adapter-Swift-Package (for example LevelPlay-UnityAds-Adapter-Swift-Package, LevelPlay-Vungle-Adapter-Swift-Package). In Xcode: File > Add Package Dependencies, enter the URL, choose an exact version and add the product to the App target. Each package pulls its network SDK and LevelPlay-Swift-Package 9.x, which resolves to the same copy the plugin uses.

Networks without an official Swift package. Not every network has one (at the time of writing, InMobi does not). Two options:

  1. Use CocoaPods for the project and add the IronSource<Network>Adapter pod.

  2. Keep SPM and wrap the adapter in a small local Swift package that mirrors the official packages: a binaryTarget pointing at the adapter zip Unity publishes for CocoaPods (the URL is in the adapter's podspec, pin its SHA-256 with swift package compute-checksum), a dependency on the network's own Swift package at the version the adapter supports, a dependency on LevelPlay-Swift-Package 9.x, and an empty Swift source file for the wrapper target. Add the local package to the App target via Add Package Dependencies > Add Local....

    // swift-tools-version: 5.9
    import PackageDescription
    
    let package = Package(
        name: "LevelPlay-Example-Adapter",
        platforms: [.iOS(.v13)],
        products: [.library(name: "ExampleAdapter", targets: ["ExampleAdapter"])],
        dependencies: [
            .package(url: "https://github.com/<network>/<Network>SDK-Swift-Package.git", exact: "<sdk version>"),
            .package(url: "https://github.com/ironsource-mobile/LevelPlay-Swift-Package.git", "9.0.0"..<"10.0.0"),
        ],
        targets: [
            .target(
                name: "ExampleAdapter", // Sources/ExampleAdapter/ExampleAdapter.swift can be empty
                dependencies: [
                    "ExampleAdapterBinary",
                    .product(name: "<NetworkSDK product>", package: "<Network>SDK-Swift-Package"),
                    .product(name: "UnityMediationSDK", package: "LevelPlay-Swift-Package"),
                ]),
            .binaryTarget(
                name: "ExampleAdapterBinary",
                url: "<adapter zip URL from the adapter podspec>",
                checksum: "<sha256>"),
        ]
    )

    Add any system libraries the network's manual-integration guide lists as linkerSettings.

After adding networks: update SKAdNetworkItems (iOS setup), rebuild both platforms and run validateIntegration().

Privacy and consent

LevelPlay recommends setting privacy signals before initialize. Pass them as consent to initialize or call setConsent first; call setConsent again whenever the user changes their choice. They map to LevelPlayPrivacySettings (Android) and LPMPrivacySettings (iOS): setGDPRConsent, setCCPA, setCOPPA. See Unity's regulation settings.

  • GDPR (EEA, UK, Switzerland): pass gdprConsent: false until a consent management platform (CMP) collected consent, then true or false according to the user's choice. If you use an IAB TCF v2 CMP (for example Google UMP), LevelPlay and many networks also read the TCF consent string the CMP stores on the device.
  • CCPA and other US state laws: ccpaDoNotSell: true when the user opted out of the sale or sharing of personal data.
  • COPPA: coppa: true for users who must get child-directed treatment. Child-directed apps should also strip the AD_ID permission on Android and should not show the ATT prompt.

App Tracking Transparency (iOS)

Without ATT authorization the IDFA is zeros and ads earn less, so ask before init:

  1. Add NSUserTrackingUsageDescription to Info.plist.
  2. Call requestTrackingAuthorization() when the app is active (iOS ignores the request while the app is still launching or in the background) and before initialize. Show your CMP first if you have one.
  3. iOS shows the system prompt only once; later calls resolve the stored status. Use getTrackingAuthorizationStatus() to read it without prompting.
const { status } = await LevelPlay.getTrackingAuthorizationStatus();
if (status === 'notDetermined') await LevelPlay.requestTrackingAuthorization();
await LevelPlay.initialize({ appKey });

Limitations

  • Native ads need per-network setup. Only networks that serve native ads through LevelPlay fill them, and each needs its adapter and a native ad configuration in the dashboard. The public demo app key has no native configuration on Android (508 "No Native Ad configurations found"); on iOS it filled from ironSource Ads in testing.
  • Native ads use the plugin's templates. Custom native layouts in HTML are not possible: the SDK requires its own native views (and the network's privacy icon) to record impressions and clicks.
  • loadBanner is one-shot per banner object (an SDK rule in 9.6.1): a second call is ignored and the SDK retries on its refresh interval. To retry right away, destroyBanner + createBanner + loadBanner.
  • -ObjC is required on iOS, also for the new APIs: without it setSegment crashes with an unrecognized selector.
  • No adInfoChanged for banners and native ads: the SDK only reports it for rewarded and interstitial ads.
  • lifetimeRevenue is not typed in ImpressionData; read it from allData.lifetimeRevenue when present.
  • Overlay ads: banners and native ads are native views above the WebView, so CSS cannot clip, transform or animate them; move them with setBannerLayout / setNativeAdRect and hide them under your own modals.

Troubleshooting

Loads fail with 509 "No fill"

Common and usually not a bug. An app that is not live in its store yet (or not approved in the LevelPlay dashboard) gets little or no real demand. Use the demo ids (LEVELPLAY_DEMO) or the Integration Test Suite with test ads to check your integration, and retry loads with a backoff in production. Unity's troubleshooting guide lists more causes.

Unity Ads: "Invalid Game ID"

The Unity Ads adapter is started with the game id configured on the Unity Ads instance in LevelPlay. If Unity Ads answers "Invalid Game ID: ..." (iOS: "Initialization failed: not found"), the Unity Ads project or game is not active, or the instance uses a game id from another project. Check the game ids in the Unity dashboard and that they belong to the project linked to your LevelPlay app.

Android build fails with "Unsupported class file major version"

Gradle for Capacitor 8 must run on JDK 21. Android Studio's bundled runtime can be newer than the Gradle version supports (for example "Unsupported class file major version 69" with Java 25). Point Gradle at a JDK 21:

export JAVA_HOME=$(/usr/libexec/java_home -v 21)   # macOS
cd android && ./gradlew assembleDebug

In Android Studio: Settings > Build, Execution, Deployment > Build Tools > Gradle > Gradle JDK.

iOS: "No such module 'IronSource'" or the package does not update

  • Run npx cap sync ios after every install or upgrade of the plugin; it rewrites CapApp-SPM/Package.swift.
  • In Xcode: File > Packages > Reset Package Caches, then Resolve Package Versions.
  • Still stuck: quit Xcode, delete ~/Library/Developer/Xcode/DerivedData/<App>-* and ~/Library/Caches/org.swift.swiftpm, then reopen.
  • CocoaPods projects: cd ios/App && pod install --repo-update.

iOS: crash or missing symbols at launch

Check the -ObjC linker flag on the App target.

Nothing happens on showRewarded

showRewarded resolves { shown: false, error: { code: -1, message: 'Ad not ready' } } when no ad is loaded for that ad unit. Make sure you called loadRewarded with the same adUnitId after initialize resolved, and wait for the loaded event (or isReady).

FAQ

Which LevelPlay API does it use? LevelPlay's ad-unit API, the current API in SDK 9.x: LevelPlay.init with an init request, LevelPlayRewardedAd / LevelPlayInterstitialAd on Android and LPMRewardedAd / LPMInterstitialAd on iOS. The legacy IronSource.* placement API is not used.

Can I use more than one ad unit per format? Yes. Every call takes an adUnitId, and the plugin keeps one native ad object per id.

Does it support banners or native ads? Yes, since 0.3.0: banners in every LevelPlay size (including adaptive and custom sizes) and native ads in two templates. See Banners and Native ads.

Does it work with Capacitor 7? Yes, since 0.3.0 (@capacitor/core >= 7.0.0). Android and iOS (Swift Package Manager) builds were checked with a Capacitor 7.6.9 app.

How is this different from capacitor-levelplay-ads? Both are Capacitor plugins for LevelPlay and both use the ad-unit API. The differences, as of capacitor-levelplay-ads 0.1.42:

| | capacitor-levelplay | capacitor-levelplay-ads | |---|---|---| | iOS integration | SPM first: Package.swift depends on LevelPlay-Swift-Package; podspec as alternative | CocoaPods first; its Package.swift does not depend on the SDK (SDK code is compiled out unless you add a package yourself) | | Formats | rewarded, interstitial, banner, native (templates) | banner, rewarded, interstitial | | Ad units | any number per format side by side, addressed by adUnitId | one ad object per format at a time | | Show result | promise resolves after close with { shown, rewarded, reward } | outcome via events | | Consent | GDPR / CCPA / COPPA flags; bring your own CMP | built-in consent flows (own consent modal, optional Usercentrics / InMobi CMP) | | Adapters | added by the app (Gradle / Swift packages / pods) | helper script that injects adapter pods from package.json |

Pick the one that fits your project.

Is the LevelPlay SDK bundled? No. The plugin declares the SDK as a dependency (Maven Central, Swift package or pod). The SDK is proprietary and covered by Unity's terms.

API

Unity LevelPlay ads (ad-unit API): rewarded, interstitial and (since 0.3.0) banner and native ads, impression-level revenue, segments and placement capping.

initialize(...)

initialize(options: InitOptions) => Promise<InitResult>

Initialise the LevelPlay SDK (LevelPlay.init). Resolves on init success, rejects with the init error (code and message from the SDK) otherwise. Calling it again after a successful init resolves immediately; concurrent calls share one init. Load ads only after this resolves.

Set consent (and on iOS ask for ATT) before calling it.

On the web it rejects as unimplemented.

| Param | Type | | ------------- | --------------------------------------------------- | | options | InitOptions |

Returns: Promise<InitResult>

Since: 0.1.0


getSdkVersion()

getSdkVersion() => Promise<InitResult>

Native LevelPlay SDK version. Works before init.

Returns: Promise<InitResult>

Since: 0.1.0


setConsent(...)

setConsent(options: ConsentOptions) => Promise<void>

Forward GDPR / CCPA / COPPA signals to LevelPlay. Call it before initialize() when you can, and again whenever the user changes their choice.

| Param | Type | | ------------- | --------------------------------------------------------- | | options | ConsentOptions |

Since: 0.1.0


setMetaData(...)

setMetaData(options: MetaDataOptions) => Promise<void>

Raw LevelPlay.setMetaData(key, value) for SDK or network-specific flags. Call it before init.

| Param | Type | | ------------- | ----------------------------------------------------------- | | options | MetaDataOptions |

Since: 0.1.0


requestTrackingAuthorization()

requestTrackingAuthorization() => Promise<TrackingResult>

iOS: show the App Tracking Transparency prompt and resolve with the resulting status. Needs NSUserTrackingUsageDescription in Info.plist. iOS only shows the prompt once; later calls resolve the stored status. Call it before initialize(), while the app is active.

Android and web: resolves unavailable.

Returns: Promise<TrackingResult>

Since: 0.1.0


getTrackingAuthorizationStatus()

getTrackingAuthorizationStatus() => Promise<TrackingResult>

Current App Tracking Transparency status without prompting (iOS). Android and web: unavailable.

Returns: Promise<TrackingResult>

Since: 0.1.0


loadRewarded(...)

loadRewarded(options: AdUnitOptions) => Promise<void>

Start loading a rewarded ad for the ad unit. The native ad object is created on first use and reused for the ad unit. Resolves once the request is issued; the outcome arrives as a loaded or loadFailed event. Load the next ad after each show.

| Param | Type | | ------------- | ------------------------------------------------------- | | options | AdUnitOptions |

Since: 0.1.0


showRewarded(...)

showRewarded(options: ShowOptions) => Promise<ShowResult>

Show a loaded rewarded ad. Resolves after the ad closed (or failed to display) with what happened. The reward and close callbacks can arrive in either order on some networks, so the plugin waits up to 1 second after the close for a late reward. Never rejects for "not ready": resolves { shown: false, rewarded: false, error } instead.

| Param | Type | | ------------- | --------------------------------------------------- | | options | ShowOptions |

Returns: Promise<ShowResult>

Since: 0.1.0


loadInterstitial(...)

loadInterstitial(options: AdUnitOptions) => Promise<void>

Start loading an interstitial ad for the ad unit. Works like loadRewarded().

| Param | Type | | ------------- | ------------------------------------------------------- | | options | AdUnitOptions |

Since: 0.1.0


showInterstitial(...)

showInterstitial(options: ShowOptions) => Promise<ShowResult>

Show a loaded interstitial. Resolves after it closed (or failed to display). Never rejects for "not ready".

| Param | Type | | ------------- | --------------------------------------------------- | | options | ShowOptions |

Returns: Promise<ShowResult>

Since: 0.1.0


isReady(...)

isReady(options: IsReadyOptions) => Promise<IsReadyResult>

isAdReady() of the native ad object for this ad unit. false when the ad unit was never loaded.

| Param | Type | | ------------- | --------------------------------------------------------- | | options | IsReadyOptions |

Returns: Promise<IsReadyResult>

Since: 0.1.0


launchTestSuite()

launchTestSuite() => Promise<void>

Open the LevelPlay Integration Test Suite. Requires initialize({ testSuite: true }) first. Development builds only. Rejects on the web.

Since: 0.1.0


validateIntegration()

validateIntegration() => Promise<void>

Write the LevelPlay integration helper report to the native log (Xcode console; Android logcat tag IntegrationHelper): SDK, adapter and network SDK versions, each VERIFIED or not. Development only.

Since: 0.1.0


getCapabilities()

getCapabilities() => Promise<Capabilities>

What this platform supports (banners, native ad templates, impression data, adInfoChanged). Works before init. Web: everything false.

Returns: Promise<Capabilities>

Since: 0.3.0


setSegment(...)

setSegment(options: SegmentOptions) => Promise<void>

Set the user segment (LevelPlay.setSegment with a LevelPlaySegment / LPMSegment). Call it before initialize() so the first ad requests use it; later calls apply to the following requests. Rejects with INVALID_ARGUMENT when customParameters break the SDK limits. Web: no-op.

| Param | Type | | ------------- | --------------------------------------------------------- | | options | SegmentOptions |

Since: 0.3.0


setDynamicUserId(...)

setDynamicUserId(options: DynamicUserIdOptions) => Promise<DynamicUserIdResult>

Set or change the dynamic user id used in server-to-server reward callbacks (LevelPlay.setDynamicUserId on both platforms). Set it before showRewarded(). Web: resolves { valid: false }.

| Param | Type | | ------------- | --------------------------------------------------------------------- | | options | DynamicUserIdOptions |

Returns: Promise<DynamicUserIdResult>

Since: 0.3.0


isPlacementCapped(...)

isPlacementCapped(options: PlacementCappedOptions) => Promise<PlacementCappedResult>

Whether a rewarded or interstitial placement is capped right now (static LevelPlayRewardedAd.isPlacementCapped / LevelPlayInterstitialAd.isPlacementCapped on Android, LPMRewardedAd.isPlacementCapped: / LPMInterstitialAd.isPlacementCapped: on iOS). Works without a loaded ad. Web: { capped: false }.

| Param | Type | | ------------- | ------------------------------------------------------------------------- | | options | PlacementCappedOptions |

Returns: Promise<PlacementCappedResult>

Since: 0.3.0


getReward(...)

getReward(options: GetRewardOptions) => Promise<Reward>

The reward configured for a rewarded ad unit or one of its placements (LevelPlayRewardedAd.getReward(placement) / LPMRewardedAd getReward(placementName:)), for "watch a video for N coins" buttons. The SDK returns { name: '', amount: 0 } when it has no reward configuration (for example before init). Web: the same empty reward.

| Param | Type | | ------------- | ------------------------------------------------------------- | | options | GetRewardOptions |

Returns: Promise<Reward>

Since: 0.3.0


createBanner(...)

createBanner(options: CreateBannerOptions) => Promise<BannerResult>

Create a banner (LevelPlayBannerAdView / LPMBannerAdView) for the ad unit and attach it, hidden, in a pass-through overlay above the WebView. Requires a finished initialize() (NOT_INITIALIZED otherwise). Rejects with ALREADY_EXISTS when bannerId is in use; destroy it first. Does not load: call loadBanner(). Web: rejects as unimplemented.

| Param | Type | | ------------- | ------------------------------------------------------------------- | | options | CreateBannerOptions |

Returns: Promise<BannerResult>

Since: 0.3.0


loadBanner(...)

loadBanner(options: BannerIdOptions) => Promise<void>

Load the banner (loadAd() / loadAdWithViewController:). The outcome arrives as bannerLoaded or bannerLoadFailed; after the first load the SDK refreshes the banner on the dashboard interval. The SDK accepts one load per banner object: calling it again has no effect (Android logs "Banner load already called"), so to retry right away after bannerLoadFailed, destroy the banner and create it again. Web: no-op.

| Param | Type | | ------------- | ----------------------------------------------------------- | | options | BannerIdOptions |

Since: 0.3.0


showBanner(...)

showBanner(options: BannerIdOptions) => Promise<BannerResult>

Make the banner visible and resume auto refresh (resumeAutoRefresh). Can be called before the load finished; the creative appears when it arrives. Web: rejects as unimplemented.

| Param | Type | | ------------- | ----------------------------------------------------------- | | options | BannerIdOptions |

Returns: Promise<BannerResult>

Since: 0.3.0


hideBanner(...)

hideBanner(options: BannerIdOptions) => Promise<void>

Hide the banner and pause auto refresh (pauseAutoRefresh) so hidden banners do not burn impressions. The view stays attached; showBanner() brings it back. Web: no-op.

| Param | Type | | ------------- | ----------------------------------------------------------- | | options | BannerIdOptions |

Since: 0.3.0


setBannerLayout(...)

setBannerLayout(options: SetBannerLayoutOptions) => Promise<BannerResult>

Move a banner (position, offsets, safe area). Resolves with the new frame. Web: rejects as unimplemented.

| Param | Type | | ------------- | ------------------------------------------------------------------------- | | options | SetBannerLayoutOptions |

Returns: Promise<BannerResult>

Since: 0.3.0


destroyBanner(...)

destroyBanner(options: BannerIdOptions) => Promise<void>

Remove the banner from the screen and destroy() it. A destroyed banner cannot be reused; create a new one. Resolves also for unknown ids. Web: no-op.

| Param | Type | | ------------- | ----------------------------------------------------------- | | options | BannerIdOptions |

Since: 0.3.0


loadNativeAd(...)

loadNativeAd(options: LoadNativeAdOptions) => Promise<void>

Load a native ad into a slot. Following the SDK rule "one native ad object per load", it destroys the slot's previous ad (hiding it if shown), builds a new LevelPlayNativeAd with the placement and loads it. The outcome arrives as nativeAdLoaded or nativeAdLoadFailed. Requires a finished initialize(). Rejects with UNSUPPORTED when getCapabilities().nativeAd is false or the template is not listed there. Web: rejects as unimplemented.

| Param | Type | | ------------- | ------------------------------------------------------------------- | | options | LoadNativeAdOptions |

Since: 0.3.0


showNativeAd(...)

showNativeAd(options: NativeAdRectOptions) => Promise<void>

Render the loaded native ad into its template, register the asset views with the SDK (NativeAdLayout.registerNativeAdViews / ISNativeAdView registerNativeAdViews:) and place it at rect above the WebView. Rejects with NOT_LOADED before nativeAdLoaded. The impression is reported by nativeAdImpression. Web: rejects as unimplemented.

| Param | Type | | ------------- | ------------------------------------------------------------------- | | options | NativeAdRectOptions |

Since: 0.3.0


setNativeAdRect(...)

setNativeAdRect(options: NativeAdRectOptions) => Promise<void>

Move or resize a shown native ad, for example after the placeholder element moved. Web: no-op.

| Param | Type | | ------------- | ------------------------------------------------------------------- | | options | NativeAdRectOptions |

Since: 0.3.0


hideNativeAd(...)

hideNativeAd(options: NativeAdIdOptions) => Promise<void>

Hide a shown native ad (the view stays registered; showNativeAd() shows it again). Web: no-op.

| Param | Type | | ------------- | --------------------------------------------------------------- | | options | NativeAdIdOptions |

Since: 0.3.0


destroyNativeAd(...)

destroyNativeAd(options: NativeAdIdOptions) => Promise<void>

Remove the native ad view and destroyAd() it. Resolves also for unknown ids. Web: no-op.

| Param | Type | | ------------- | --------------------------------------------------------------- | | options | NativeAdIdOptions |

Since: 0.3.0


addListener('loaded', ...)

addListener(eventName: 'loaded', listenerFunc: (event: AdEvent) => void) => Promise<PluginListenerHandle>

An ad finished loading for the ad unit and can be shown.

| Param | Type | | ------------------ | --------------------------------------------------------------- | | eventName | 'loaded' | | listenerFunc | (event: AdEvent) => void |

Returns: Promise<PluginListenerHandle>

Since: 0.1.0


addListener('loadFailed', ...)

addListener(eventName: 'loadFailed', listenerFunc: (event: AdErrorEvent) => void) => Promise<PluginListenerHandle>

Loading failed, for example 509 (no fill). Retry later with a backoff.

| Param | Type | | ------------------ | ------------------------------------------------------------------------- | | eventName | 'loadFailed' | | listenerFunc | (event: AdErrorEvent) => void |

Returns: Promise<PluginListenerHandle>

Since: 0.1.0


addListener('displayed', ...)

addListener(eventName: 'displayed', listenerFunc: (event: AdEvent) => void) => Promise<PluginListenerHandle>

The ad was displayed (impression). adInfo.revenue is available here.

| Param | Type | | ------------------ | --------------------------------------------------------------- | | eventName | 'displayed' | | listenerFunc | (event: AdEvent) => void |

Returns: Promise<PluginListenerHandle>

Since: 0.1.0


addListener('displayFailed', ...)

addListener(eventName: 'displayFailed', listenerFunc: (event: AdErrorEvent) => void) => Promise<PluginListenerHandle>

The ad failed to display. The pending show call resolves with the same error.

| Param | Type | | ------------------ | ------------------------------------------------------------------------- | | eventName | 'displayFailed' | | listenerFunc | (event: AdErrorEvent) => void |

Returns: Promise<PluginListenerHandle>

Since: 0.1.0


addListener('clicked', ...)

addListener(eventName: 'clicked', listenerFunc: (event: AdEvent) => void) => Promise<PluginListenerHandle>

The user clicked the ad.

| Param | Type | | ------------------ | --------------------------------------------------------------- | | eventName | 'clicked' | | listenerFunc | (event: AdEvent) => void |

Returns: Promise<PluginListenerHandle>

Since: 0.1.0


addListener('closed', ...)

addListener(eventName: 'closed', listenerFunc: (event: AdEvent) => void) => Promise<PluginListenerHandle>

The ad was closed and the app is back in front.

| Param | Type | | ------------------ | --------------------------------------------------------------- | | eventName | 'closed' | | listenerFunc | (event: AdEvent) => void |

Returns: Promise<PluginListenerHandle>

Since: 0.1.0


addListener('rewarded', ...)

addListener(eventName: 'rewarded', listenerFunc: (event: AdRewardEvent) => void) => Promise<PluginListenerHandle>

Rewarded only: the user earned the reward. Can fire before or after closed.

| Param | Type | | ------------------ | --------------------------------------------------------------------------- | | eventName | 'rewarded' | | listenerFunc | (event: AdRewardEvent) => void |

Returns: Promise<PluginListenerHandle>

Since: 0.1.0


addListener('adInfoChanged', ...)

addListener(eventName: 'adInfoChanged', listenerFunc: (event: AdEvent) => void) => Promise<PluginListenerHandle>

Rewarded and interstitial: the SDK reloaded the ad in the background and its ad info (network, revenue ...) changed (onAdInfoChanged / didChangeAdInfo:). Banners and native ads have no such callback in SDK 9.6.1.

| Param | Type | | ------------------ | --------------------------------------------------------------- | | eventName | 'adInfoChanged' | | listenerFunc | (event: AdEvent) => void |

Returns: Promise<PluginListenerHandle>

Since: 0.3.0


addListener('impressionData', ...)

addListener(eventName: 'impressionData', listenerFunc: (event: ImpressionData) => void) => Promise<PluginListenerHandle>

Impression-level revenue data for every rewarded, interstitial and banner impression (per-ad setImpressionDataListener / setImpressionDataDelegate:, attached by the plugin to every ad object it creates), plus native ad impressions synthesised from the native ad info (adFormat: 'nativead', adInfo fields only). Add the listener at any time, also before initialize(); nothing is delivered before the first ad shows.

| Param | Type | | ------------------ | ----------------------------------------------------------------------------- | | eventName | 'impressionData' | | listenerFunc | (event: ImpressionData) => void |

Returns: Promise<PluginListenerHandle>

Since: 0.3.0


addListener('bannerLoaded', ...)

addListener(eventName: 'bannerLoaded', listenerFunc: (event: BannerEvent) => void) => Promise<PluginListenerHandle>

A banner loaded or refreshed with a new creative.

| Param | Type | | ------------------ | ----------------------------------------------------------------------- | | eventName | 'bannerLoaded' | | listenerFunc | (event: BannerEvent) => void |

Returns: Promise<PluginListenerHandle>

Since: 0.3.0


addListener('bannerLoadFailed', ...)

addListener(eventName: 'bannerLoadFailed', listenerFunc: (event: BannerErrorEvent) => void) => Promise<PluginListenerHandle>

A banner load (or refresh) failed. The SDK keeps retrying on its refresh interval.

| Param | Type | | ------------------ | --------------------------------------------------------------------------------- | | eventName | 'bannerLoadFailed' | | listenerFunc | (event: BannerErrorEvent) => void |

Returns: Promise<PluginListenerHandle>

Since: 0.3.0


addListener('bannerDisplayed', ...)

addListener(eventName: 'bannerDisplayed', listenerFunc: (event: BannerEvent) => void) => Promise<PluginListenerHandle>

A banner creative was displayed on screen (impression).

| Param | Type | | ------------------ | ----------------------------------------------------------------------- | | eventName | 'bannerDisplayed' | | listenerFunc | (event: BannerEvent) => void |

Returns: Promise<PluginListenerHandle>

Since: 0.3.0


addListener('bannerDisplayFailed', ...)

addListener(eventName: 'bannerDisplayFailed', listenerFunc: (event: BannerErrorEvent) => void) => Promise<PluginListenerHandle>

A banner creative failed to display.

| Param | Type | | ------------------ | --------------------------------------------------------------------------------- | | eventName | 'bannerDisplayFailed' | | listenerFunc | (event: BannerErrorEvent) => void |

Returns: Promise<PluginListenerHandle>

Since: 0.3.0