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
- Swift
- Objective-C
import EmpowerMobileAds@mainclass AppDelegate: UIResponder, UIApplicationDelegate {var window: UIWindow?private let zoneId = "YOUR_APP_OPEN_ZONE_ID"func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {// Initialize the SDKEMAManager.shared.initialize(appAdIdentifier: "your_app_identifier")// Preload the App Open adEMAManager.shared.loadAppOpen(zoneId: zoneId)return true}func applicationDidBecomeActive(_ application: UIApplication) {// Show the ad when the app becomes activeif EMAManager.shared.isAppOpenReady(zoneId: zoneId),let rootVC = window?.rootViewController {EMAManager.shared.showAppOpen(zoneId: zoneId, from: rootVC)}// Preload for next timeEMAManager.shared.loadAppOpen(zoneId: zoneId)}}
Implementation
Only show an App Open ad when the user returns after a meaningful time in the background, and never on the very first cold start (let your content load first).
AppDelegate
- Swift
- Objective-C
import EmpowerMobileAds@mainclass 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 {EMAManager.shared.initialize(appAdIdentifier: "your_app_identifier")EMAManager.shared.loadAppOpen(zoneId: zoneId, delegate: self)return true}func applicationDidEnterBackground(_ application: UIApplication) {backgroundTime = Date()}func applicationDidBecomeActive(_ application: UIApplication) {showAppOpenAdIfAppropriate()}private func showAppOpenAdIfAppropriate() {if let backgroundTime = backgroundTime,Date().timeIntervalSince(backgroundTime) >= 30, // at least 30 secondsEMAManager.shared.isAppOpenReady(zoneId: zoneId),let rootVC = window?.rootViewController {EMAManager.shared.showAppOpen(zoneId: zoneId, from: rootVC)}backgroundTime = nil// Always preload for next timeEMAManager.shared.loadAppOpen(zoneId: zoneId, delegate: self)}// MARK: - AdStatusDelegate (optional)func empowerAppOpenStatusChanged(adStatus: AdStatus) {switch adStatus {case .ready:print("App Open ad is ready")case .failed:print("App Open ad failed to load")DispatchQueue.main.asyncAfter(deadline: .now() + 60) { [weak self] inguard let self = self else { return }EMAManager.shared.loadAppOpen(zoneId: self.zoneId, delegate: self)}case .shown:print("App Open ad is showing")case .closed:print("App Open ad closed")default:break}}}
SceneDelegate (iOS 13+)
For apps using UISceneDelegate, wire the same logic into the scene lifecycle:
- Swift
- Objective-C
import EmpowerMobileAdsclass 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) {EMAManager.shared.loadAppOpen(zoneId: zoneId, delegate: self)}func sceneDidEnterBackground(_ scene: UIScene) {backgroundTime = Date()}func sceneDidBecomeActive(_ scene: UIScene) {if let backgroundTime = backgroundTime,Date().timeIntervalSince(backgroundTime) >= 30,EMAManager.shared.isAppOpenReady(zoneId: zoneId),let rootVC = window?.rootViewController {EMAManager.shared.showAppOpen(zoneId: zoneId, from: rootVC)}backgroundTime = nilEMAManager.shared.loadAppOpen(zoneId: zoneId, delegate: self)}func empowerAppOpenStatusChanged(adStatus: AdStatus) {// Handle status changes if needed}}
Status Values
Swift (AdStatus) | Objective-C (EMAAdStatusType) | Description |
|---|---|---|
.initializing | EMAAdStatusTypeInitializing | Ad is loading |
.ready | EMAAdStatusTypeReady | Ad is ready to show |
.shown | EMAAdStatusTypeShown | Ad is currently showing |
.failed(Error?) | EMAAdStatusTypeFailed | Ad failed to load |
.closed | EMAAdStatusTypeClosed | Ad was shown and closed |
In Swift, adopt AdStatusDelegate and implement empowerAppOpenStatusChanged(adStatus:).
In Objective-C, adopt EMAAdObserver and implement appOpenStatusChanged:.
Best Practices
- Don't show on every return — only after a meaningful background time (30+ seconds).
- Respect user experience — don't interrupt critical user flows.
- Always preload — call the load method again after showing to prepare for next time.
- Don't block app launch — let content load first on cold start.
- Skip during critical flows — don't show during checkout, onboarding, etc.
Troubleshooting
- Swift
- Objective-C
print("Ad ready: \(EMAManager.shared.isAppOpenReady(zoneId: "YOUR_ZONE_ID"))")print("SDK initialized: \(EMAManager.shared.isSdkInitialized)")EMASettings.shared.logLevel = .all
API Reference
func loadAppOpen(zoneId: String, delegate: AdStatusDelegate? = nil)func isAppOpenReady(zoneId: String) -> Boolfunc showAppOpen(zoneId: String, from viewController: UIViewController)
Objective-C selectors
| Swift | Objective-C selector |
|---|---|
loadAppOpen(zoneId:delegate:) | loadAppOpenAdWithZoneId:observer: |
isAppOpenReady(zoneId:) | isAppOpenReadyForZoneId: |
showAppOpen(zoneId:from:) | showAppOpenWithZoneId:fromViewController: |