Skip to main content

Preroll Ads

Preroll ads are video ads that play before your content in a video player container. The SDK renders and auto-plays the ad inside a UIView you provide, using Google IMA — there is no separate "show" call. Users can skip the ad when the VAST creative allows it.

When the ad finishes, is skipped, or fails, you start your own content playback — typically from the delegate callbacks (onAdCompleted / onAdSkipped / onAdFailed).

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

Note: The preroll API is Swift-only — loading a preroll from Objective-C is not supported. The delegate is optional; use it only if you need to react to ad states for analytics, UI, or to trigger your content player.

Container Setup

Add a UIView to your layout as the video ad container:

Create a UIView in your storyboard and connect it as an IBOutlet:

@IBOutlet weak var playerView: UIView!

Loading a Preroll Ad

Call loadPrerollAd(zoneId:playerView:muted:delegate:). The SDK loads the ad and auto-plays it inside playerView as soon as it is ready — you do not call a separate show method. If the SDK is not fully initialized yet, the request is queued and runs automatically once it is ready.

import EmpowerMobileAds

class VideoViewController: UIViewController {
@IBOutlet weak var playerView: UIView!

private let zoneId = "YOUR_PREROLL_ZONE_ID"

override func viewDidLoad() {
super.viewDidLoad()

EMAManager.shared.loadPrerollAd(
zoneId: zoneId,
playerView: playerView,
muted: false,
delegate: self
)
}

private func startContentPlayback() {
// Start your own AVPlayer / video content here.
}

deinit {
EMAManager.shared.destroyPreroll(zoneId: zoneId)
}
}

extension VideoViewController: PrerollAdDelegate {
func onAdReady() {} // loaded, about to auto-play
func onAdStarted() {} // playback started
func onAdCompleted() { startContentPlayback() }
func onAdSkipped() { startContentPlayback() }
func onAdFailed(error: String) { startContentPlayback() }
func onAdClicked() {}
}

That's it — the SDK loads the ad and auto-plays it. Use the delegate's terminal callbacks (onAdCompleted / onAdSkipped / onAdFailed) to start your content video.

Parameters

ParameterTypeRequiredDefaultDescription
zoneIdStringYesThe zone ID for the preroll placement
playerViewUIViewYesThe container view where the ad is rendered and auto-played
mutedBoolNofalseWhether the ad should start muted
delegatePrerollAdDelegate?NonilDelegate to receive preroll ad events

Handling Preroll Events (Optional)

Adopt PrerollAdDelegate to react to the ad lifecycle. All methods are called on the main thread.

extension VideoViewController: PrerollAdDelegate {
func onAdReady() {
// Ad loaded and about to auto-play.
}

func onAdStarted() {
// Ad playback started.
}

func onAdCompleted() {
// Ad finished — start your content video.
startContentPlayback()
}

func onAdSkipped() {
// User skipped the ad — start your content video.
startContentPlayback()
}

func onAdFailed(error: String) {
// Ad failed to load or play — start your content video.
print("Preroll failed: \(error)")
startContentPlayback()
}

func onAdClicked() {
// User tapped the ad.
}
}

Lifecycle Management

Preroll zones are managed by EMAManager.shared and keyed by zoneId. Pause, resume, and destroy them through the manager — there is no per-ad handle to hold onto:

// Pause playback (e.g., the view scrolled off-screen or the app backgrounded)
EMAManager.shared.pausePreroll(zoneId: zoneId)

// Resume playback
EMAManager.shared.resumePreroll(zoneId: zoneId)

// Release the zone when the ad is no longer needed (e.g., in deinit)
EMAManager.shared.destroyPreroll(zoneId: zoneId)
MethodDescription
pausePreroll(zoneId:)Pauses playback for the given zone
resumePreroll(zoneId:)Resumes playback for the given zone
destroyPreroll(zoneId:)Releases IMA resources and removes the ad for the given zone

Loading Overlay

By default the SDK shows a built-in loading overlay (shimmer + progress) over playerView while the ad loads. To manage your own loading UI instead, disable it before loading:

EMAManager.shared.showPrerollLoadingOverlay = false

Best Practices

  • Start content in the terminal callbacks — begin your own playback in onAdCompleted, onAdSkipped, and onAdFailed so the user always reaches the content whether the ad succeeds, is skipped, or fails.
  • Destroy on teardown — call destroyPreroll(zoneId:) in deinit (or when leaving the screen) to release IMA resources.
  • Mute in silent contexts — pass muted: true when the video auto-plays in a feed or other silent context.
  • Frequency capping — the SDK respects server-configured session frequency caps; a zoneId that is capped will report onAdFailed/no fill, so always have the content-fallback path wired up.

Ad Event Reference

CallbackDescription
onAdReady()Ad is loaded and about to auto-play
onAdStarted()Ad playback started
onAdCompleted()Ad finished playing — start your content
onAdSkipped()User skipped the ad — start your content
onAdFailed(error:)Ad failed to load or play — start your content
onAdClicked()User clicked the ad