App Open Ads

App open ads appear when users bring your app to the foreground, providing a monetization opportunity during app launches.

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
@main
class AppDelegate: UIResponder, UIApplicationDelegate, AdStatusDelegate {
var window: UIWindow?
private let zoneId = "YOUR_APP_OPEN_ZONE_ID"
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize SDK
EMAManager.shared.initAd("your_app_identifier")
// Preload App Open ad
EMAManager.shared.loadAppOpen(zoneId: zoneId)
return true
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Show ad when app becomes active
EMAManager.shared.MAManager.shared.showAppOpen(from: rootVC)
// Preload for next time
EMAManager.shared.loadAppOpen(zoneId: zoneId)
}
}

Implementation

AppDelegate (iOS 12 and earlier)

import EmpowerMobileAds
@main
class AppDelegate: UIResponder, UIApplicationDelegate, AdStatusDelegate {
var window: UIWindow?
private var backgroundTime: Date?
private let zoneId = "YOUR_APP_OPEN_ZONE_ID"
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize SDK
EMAManager.shared.initAd("your_app_identifier")
// Setup App Open ad with delegate (optional)
EmpowerAppOpenManager.shared.delegate = self
EMAManager.shared.loadAppOpen(zoneId: zoneId)
return true
}
func applicationDidEnterBackground(_ application: UIApplication) {
backgroundTime = Date()
}
func applicationDidBecomeActive(_ application: UIApplication) {
showAppOpenAdIfAppropriate()
}
private func showAppOpenAdIfAppropriate() {
// Only show if user was in background for a meaningful time
if let backgroundTime = backgroundTime {
let timeInBackground = Date().timeIntervalSince(backgroundTime)
if timeInBackground >= 30 { // At least 30 seconds
MAManager.shared.showAppOpen(from: rootVC)
}
}
backgroundTime = nil
// Always preload for next time
EMAManager.shared.loadAppOpen(zoneId: zoneId)
}
// MARK: - AdStatusDelegate (Optional)
func empowerAppOpenStatusChanged(_ manager: EmpowerAppOpenManager) {
switch manager.status {
case .ready:
print("App Open ad is ready")
case .failed:
print("App Open ad failed to load")
// Retry after delay
DispatchQueue.main.asyncAfter(deadline: .now() + 60) { [weak self] in
guard let self = self else { return }
EMAManager.shared.loadAppOpen(zoneId: self.zoneId)
}
case .present:
print("App Open ad is showing")
case .used:
print("App Open ad closed")
// Ad is automatically reloaded after show
default:
break
}
}
}

SceneDelegate (iOS 13+)

For apps using UISceneDelegate:

import EmpowerMobileAds
class SceneDelegate: UIResponder, UIWindowSceneDelegate, AdStatusDelegate {
var window: UIWindow?
private var backgroundTime: Date?
private let zoneId = "YOUR_APP_OPEN_ZONE_ID"
func scene(_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
// Setup App Open ad with delegate (optional)
EmpowerAppOpenManager.shared.delegate = self
EMAManager.shared.loadAppOpen(zoneId: zoneId)
}
func sceneDidEnterBackground(_ scene: UIScene) {
backgroundTime = Date()
}
func sceneDidBecomeActive(_ scene: UIScene) {
showAppOpenAdIfAppropriate()
}
private func showAppOpenAdIfAppropriate() {
if let backgroundTime = backgroundTime {
let timeInBackground = Date().timeIntervalSince(backgroundTime)
if timeInBackground >= 30 {
MAManager.shared.showAppOpen(from: rootVC)
}
}
backgroundTime = nil
EMAManager.shared.loadAppOpen(zoneId: zoneId)
}
func empowerAppOpenStatusChanged(_ manager: EmpowerAppOpenManager) {
// Handle status changes if needed
}
}

Status Handling

AdStatusDelegate

func empowerAppOpenStatusChanged(_ manager: EmpowerAppOpenManager) {
switch manager.status {
case .initializing:
print("App Open ad loading...")
case .ready:
print("App Open ad ready to show")
case .failed:
print("App Open ad failed to load")
retryLoad()
case .present:
print("App Open ad is displaying")
// Optionally pause content
case .used:
print("App Open ad was closed")
// Ad is automatically reloaded
default:
break
}
}

Status Values

StatusDescription
.initializingAd is loading
.readyAd is ready to show
.presentAd is currently showing
.failedAd failed to load
.usedAd was shown and closed

SwiftUI Integration

import SwiftUI
import EmpowerMobileAds
// MARK: - App Open Ad Manager
class AppOpenAdManager: NSObject, ObservableObject, AdStatusDelegate {
static let shared = AppOpenAdManager()
@Published var isReady = false
private var backgroundTime: Date?
private let zoneId = "YOUR_ZONE_ID"
private let minimumBackgroundDuration: TimeInterval = 30
override init() {
super.init()
EmpowerAppOpenManager.shared.delegate = self
preload()
}
func preload() {
EMAManager.shared.loadAppOpen(zoneId: zoneId)
}
func appDidEnterBackground() {
backgroundTime = Date()
}
func appDidBecomeActive() {
defer {
backgroundTime = nil
preload()
}
guard let backgroundTime = backgroundTime else { return }
let duration = Date().timeIntervalSince(backgroundTime)
guard duration >= minimumBackgroundDuration else { return }
MAManager.shared.showAppOpen(from: rootVC)
}
func empowerAppOpenStatusChanged(_ manager: EmpowerAppOpenManager) {
DispatchQueue.main.async {
self.isReady = manager.status == .ready
}
}
}
// MARK: - SwiftUI App
@main
struct MyApp: App {
@StateObject private var appOpenManager = AppOpenAdManager.shared
@Environment(\.scenePhase) private var scenePhase
init() {
EMAManager.shared.initAd("your_app_identifier")
}
var body: some Scene {
WindowGroup {
ContentView()
.onChange(of: scenePhase) { newPhase in
switch newPhase {
case .active:
appOpenManager.appDidBecomeActive()
case .background:
appOpenManager.appDidEnterBackground()
default:
break
}
}
}
}
}

Best Practices

  1. Don't Show on Every Return - Only show after meaningful background time (30+ seconds)
  2. Respect User Experience - Don't interrupt critical user flows
  3. Always Preload - Call loadAppOpen after showing to prepare for next time
  4. Don't Block App Launch - Let content load first on cold start
  5. Skip During Critical Flows - Don't show during checkout, onboarding, etc.

Troubleshooting

Ad Not Showing

Check availability:

print("Ad available: \(EMAManager.shared.isAppOpenReady())")

Enable debug logging:

EMASettings.shared.logLevel = .all

Ad Not Loading

  1. Check zone ID is correct
  2. Check network connectivity
  3. Check SDK is initialized:
print("SDK initialized: \(EMAManager.shared.isSdkInitialized())")

AdStatusDelegate

MethodDescription
empowerAppOpenStatusChanged(_:)Called when App Open ad status changes