Interstitial Ads

Interstitial ads are full-screen ads that cover the interface. Display them at natural pause points in your app, such as between game levels or after completing a task.

Each ad format uses a Zone ID to identify the ad placement. Zone IDs are configured in the Empower dashboard.

Note: All ad status listeners are optional. The SDK handles ad loading and display automatically. Use listeners only if you need to track ad states for analytics, UI updates, or custom logic.


Quick Start

import EmpowerMobileAds
class HomeViewController: UIViewController, AdStatusDelegate {
private let interstitialZoneId = "YOUR_INTERSTITIAL_ZONE_ID"
override func viewDidLoad() {
super.viewDidLoad()
loadInterstitial()
}
func loadInterstitial() {
EMAManager.shared.loadInterstitialAd(zoneId: interstitialZoneId, delegate: self)
}
func showInterstitialIfReady() {
if EMAManager.shared.isInterstitialReady(zoneId: interstitialZoneId) {
EMAManager.shared.showInterstitial(zoneId: interstitialZoneId, from: self)
} else {
print("Interstitial not ready")
}
}
func empowerInterstitialStatusChanged(adStatus: AdStatus) {
switch adStatus {
case .ready:
print("Interstitial ready to show")
case .failed(let error):
print("Interstitial failed to load: \(error?.localizedDescription ?? "unknown")")
case .closed:
loadInterstitial() // Preload next
default:
break
}
}
}

Loading Interstitials

Basic Loading

EMAManager.shared.loadInterstitialAd(zoneId: "YOUR_ZONE_ID", delegate: self)

Showing Interstitials

Check Readiness First

Always verify the ad is ready before showing:

func showInterstitial() {
let zoneId = "YOUR_ZONE_ID"
if EMAManager.shared.isInterstitialReady(zoneId: zoneId) {
EMAManager.shared.showInterstitial(zoneId: zoneId, from: self)
} else {
print("Interstitial not ready yet")
// Optionally show without ad or wait
}
}

Automatic Presentation

You can use showInterstitialAutomatic to automatically present from the topmost view controller. If the ad isn't ready yet, the request is queued and the ad will be shown when it becomes available:

EMAManager.shared.showInterstitialAutomatic(zoneId: "YOUR_ZONE_ID")

Status Handling

Status Flow

loadInterstitialAd() → .initializing → .ready → showInterstitial(zoneId:from:) → .shown → .closed
.failed (retry)

AdStatusDelegate

extension HomeViewController: AdStatusDelegate {
func empowerInterstitialStatusChanged(adStatus: AdStatus) {
switch adStatus {
case .initializing:
print("Interstitial is loading...")
case .ready:
print("Interstitial ready to show")
case .shown:
print("Interstitial is currently displaying")
case .closed:
print("Interstitial was closed")
loadInterstitial() // Preload next
case .failed(let error):
print("Interstitial failed: \(error?.localizedDescription ?? "unknown")")
case .clicked:
print("Interstitial was clicked")
case .willLeave:
print("User is leaving the app")
case .impression:
print("Impression recorded")
default:
break
}
}
}

Status Values

StatusDescription
.initializingAd is loading
.readyAd is ready to show
.shownAd is currently displaying
.failed(Error?)Ad failed to load (with optional error)
.closedAd was closed/dismissed
.clickedAd was clicked
.willLeaveUser clicked, leaving app
.impressionImpression was recorded

SwiftUI Integration

import SwiftUI
import EmpowerMobileAds
// MARK: - Interstitial Coordinator
class InterstitialCoordinator: NSObject, ObservableObject, AdStatusDelegate {
@Published var isReady = false
@Published var isShowing = false
private let zoneId: String
init(zoneId: String) {
self.zoneId = zoneId
super.init()
load()
}
func load() {
EMAManager.shared.loadInterstitialAd(zoneId: zoneId, delegate: self)
}
func show() {
guard isReady else { return }
// Get root view controller for SwiftUI
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let rootVC = windowScene.windows.first?.rootViewController else { return }
EMAManager.shared.showInterstitial(zoneId: zoneId, from: rootVC)
}
func empowerInterstitialStatusChanged(adStatus: AdStatus) {
DispatchQueue.main.async {
switch adStatus {
case .ready:
self.isReady = true
self.isShowing = false
case .shown:
self.isShowing = true
case .closed:
self.isReady = false
self.isShowing = false
self.load() // Reload
case .failed:
self.isReady = false
self.isShowing = false
self.load() // Retry
default:
break
}
}
}
}
// MARK: - Usage in SwiftUI View
struct HomeView: View {
@StateObject private var interstitial = InterstitialCoordinator(zoneId: "YOUR_ZONE_ID")
@State private var level = 1
var body: some View {
VStack {
Text("Level \(level)")
.font(.largeTitle)
Button("Complete Level") {
completeLevel()
}
.buttonStyle(.borderedProminent)
}
}
private func completeLevel() {
level += 1
// Show interstitial every 3 levels
if level % 3 == 0 && interstitial.isReady {
interstitial.show()
}
}
}

Troubleshooting

Interstitial Not Showing

  1. Ensure you're passing a valid view controller:
EMAManager.shared.showInterstitial(zoneId: "YOUR_ZONE_ID", from: self) // 'self' must be a UIViewController
  1. Check ads are not disabled:
print("Ads disabled: \(EMASettings.shared.isAdsDisabled)")
  1. Enable debug logging:
EMASettings.shared.logLevel = .all

API Reference

EMAManager.loadInterstitialAd

func loadInterstitialAd(
zoneId: String,
delegate: AdStatusDelegate? = nil
)
ParameterTypeDescription
zoneIdStringYour interstitial zone ID
delegateAdStatusDelegate?Callback delegate

EMAManager.showInterstitial

func showInterstitial(
zoneId: String,
from viewController: UIViewController
)
ParameterTypeDescription
zoneIdStringThe zone identifier for the interstitial to show
viewControllerUIViewControllerThe view controller to present from

EMAManager.showInterstitialAutomatic

@discardableResult
func showInterstitialAutomatic(zoneId: String) -> Bool

Shows the interstitial from the topmost view controller automatically. If the ad is not ready yet, the request is queued and executed when the ad becomes available. Returns true if the ad was shown immediately, false otherwise.

EMAManager.isInterstitialReady

func isInterstitialReady(zoneId: String) -> Bool

Returns true if the interstitial ad for the specified zone is ready to show.