iOS SDK Configuration

Initializing the SDK

SDK Initialization

Initialize the SDK as early as possible in your app lifecycle, preferably in AppDelegate.

Basic Initialization

import EmpowerMobileAds
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize the SDK with your app identifier
let config = EMAConfiguration(appAdIdentifier: "YOUR_APP_AD_IDENTIFIER")
EMAManager.shared.initialize(configuration: config)
return true
}
}

Initialization with Options

// Initialize with debug logging enabled
let config = EMAConfiguration(
appAdIdentifier: "YOUR_APP_AD_IDENTIFIER",
logLevel: .all
)
EMAManager.shared.initialize(configuration: config)

Or using the convenience initializer for minimal setup:

EMAManager.shared.initialize(appAdIdentifier: "YOUR_APP_AD_IDENTIFIER")

appAdIdentifier: Your app identifier which will be provided by us.

EMAConfiguration Parameters

ParameterTypeDefaultDescription
appAdIdentifierStringRequiredThe app identifier provided by Empower
adAppVersionString"1"The ad app version
variantString""A/B test variant string
logLevelLogLevel.noneLogging level for SDK debug output
nonPersonalizedAdsBoolfalseWhen true, requests non-personalized ads only (GDPR)
customUserIdString?nilCustom user identifier
customParameters[String: String]?nilAdditional custom parameters for ad requests
appLovinSdkKeyString?nilAppLovin SDK key (required if using AppLovin mediation)

Factory Methods

Swift only. The factory methods and the builder pattern below operate on the EMAConfiguration struct, which is not available in Objective-C. Objective-C apps configure the SDK through the initializeWithAppAdIdentifier:adAppVersion:variant:logLevel:nonPersonalizedAds: method shown above, and adjust the rest at runtime via EMASettings.shared.

// Basic configuration with defaults
let config = EMAConfiguration.basic(appAdIdentifier: "YOUR_APP_AD_IDENTIFIER")
// Debug configuration with .all log level
let config = EMAConfiguration.debug(appAdIdentifier: "YOUR_APP_AD_IDENTIFIER")
// GDPR-compliant configuration with non-personalized ads enabled
let config = EMAConfiguration.gdprCompliant(appAdIdentifier: "YOUR_APP_AD_IDENTIFIER")

Builder Pattern

You can chain configuration options using the builder pattern:

let config = EMAConfiguration.basic(appAdIdentifier: "YOUR_APP_AD_IDENTIFIER")
.with(logLevel: .all)
.with(variant: "variant_b")
.with(nonPersonalizedAds: true)
.with(customUserId: "user_123")
.with(customParameters: ["category": "news"])
.with(appLovinSdkKey: "YOUR_APPLOVIN_SDK_KEY")
EMAManager.shared.initialize(configuration: config)

Runtime Settings

You can modify certain settings at runtime via EMASettings.shared:

SettingTypeDefaultDescription
logLevelLogLevel.noneLog verbosity
isAdsDisabledBoolfalseDisable all ads (e.g., for premium users)
isAdsNonPersonalizedBoolfalseRequest non-personalized ads

Log Levels

SwiftObjective-CDescription
.noneLogLevelNoneDisables all logging
.allLogLevelAllLogs all messages including debug information
.normalLogLevelNormalStandard logging level for general information
.errorLogLevelErrorLogs errors only
.warningLogLevelWarningLogs warnings and errors

Runtime settings are identical in both languages via EMASettings.shared, e.g. EMASettings.shared.logLevel = .all (Swift) / EMASettings.shared.logLevel = LogLevelAll; (Objective-C).

Impression Level Ad Revenue (ILRD) Integration

Available since EmpowerMobileAds SDK 9.4.9


Overview

Impression Level Ad Revenue (ILRD) lets you receive per-impression revenue data from AppLovin MAX and Google (AdMob / Ad Manager). Each time an ad generates a paid impression, the SDK calls your delegate with a structured EMAAdRevenue object containing the revenue details.

Supported ad formats: Banner, Interstitial, Rewarded, App Open


1. Implement EMAAdRevenueDelegate

extension YourViewController: EMAAdRevenueDelegate {
func empowerAdRevenueReceived(_ revenue: EMAAdRevenue) {
// revenue.adFormat → "BANNER", "INTERSTITIAL", "REWARDED", "APP_OPEN"
// revenue.zoneId → Empower zone ID (e.g. "161428")
// revenue.provider → "APPLOVIN_MAX", "GOOGLE_ADMOB", "GOOGLE_AD_MANAGER"
// revenue.adUnitId → Ad network unit ID
// revenue.valueMicros → Revenue in micros (e.g. 868 = $0.000868)
// revenue.currencyCode → "USD"
"ESTIMATED", "PUBLISHER_PROVIDED", "UNKNOWN"
// revenue.eventTimeMillis → Unix timestamp in milliseconds
print("Revenue: \(revenue.valueMicros) micros from \(revenue.provider.rawValue)")
}
}

2. Register the Delegate

Assign before the SDK starts loading ads — typically in viewDidLoad or AppDelegate.

EMAManager.shared.adRevenueDelegate = self

Note: The delegate is a weak reference. Make sure the object stays alive for the duration you want to receive events.


3. Revenue Model Reference

EMAAdRevenue

FieldTypeDescription
adFormatEMAAdFormatAd format enum
zoneIdStringEmpower zone identifier
providerEMAAdProviderAd network that served the ad
adUnitIdStringAd network's unit ID
valueMicrosInt64Revenue × 1,000,000 (avoids float precision loss)
currencyCodeStringAlways "USD"
eventTimeMillisInt64Unix timestamp (ms) of the impression

Notes

  • ILRD fires only when an ad impression occurs, not on load.
  • Preroll (IMA) ads are not supported — the IMA SDK does not provide per-impression revenue data.
  • Test ads may report valueMicros = 0 or may not fire at all depending on the network.

Listening for SDK Ready State (Optional)

If you need to know exactly when the SDK is ready (for analytics, UI updates, etc.), you can implement EMASdkReadyDelegate (Swift only — Objective-C apps use the notification shown below):

import EmpowerMobileAds
@main
class AppDelegate: UIResponder, UIApplicationDelegate, EMASdkReadyDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Register as delegate before initialization
EMAManager.shared.sdkReadyDelegate = self
// Initialize the SDK
let config = EMAConfiguration(appAdIdentifier: "YOUR_APP_AD_IDENTIFIER")
EMAManager.shared.initialize(configuration: config)
return true
}
// MARK: - EMASdkReadyDelegate
func onReady() {
// SDK is initialized and ready to load ads
// Use this for analytics or UI updates
print("Empower SDK is ready")
}
func onFailed(error: Error?) {
// SDK initialization failed
// Handle the error appropriately
print("Empower SDK initialization failed: \(error?.localizedDescription ?? "unknown")")
}
}

Alternatively, you can observe the SDK-ready notification. This is the recommended approach for Objective-C, where EMASdkReadyDelegate is not available:

NotificationCenter.default.addObserver(
forName: EMAManager.adsReadyToLoadNotification,
object: nil,
queue: .main
) { _ in
print("SDK is ready to load ads")
}

Note: This delegate is optional. Since all ad types automatically queue, you don't need to wait for onReady() before loading ads.


GDPR Compliance

For users in regions requiring GDPR compliance, enable non-personalized ads:

// Option 1: Use GDPR-compliant configuration
let config = EMAConfiguration.gdprCompliant(appAdIdentifier: "YOUR_APP_AD_IDENTIFIER")
EMAManager.shared.initialize(configuration: config)
// Option 2: Set via configuration parameter
let config = EMAConfiguration(
appAdIdentifier: "YOUR_APP_AD_IDENTIFIER",
nonPersonalizedAds: true
)
EMAManager.shared.initialize(configuration: config)
// Option 3: At runtime based on user consent
EMASettings.shared.isAdsNonPersonalized = !userHasGivenConsent

App Tracking Transparency (iOS 14+)

For iOS 14 and later, you should request App Tracking Transparency permission before initializing the SDK:

import AppTrackingTransparency
import EmpowerMobileAds
func requestTrackingPermissionAndInitSDK() {
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { status in
DispatchQueue.main.async {
let nonPersonalized: Bool
switch status {
case .authorized:
// User granted permission - personalized ads enabled
nonPersonalized = false
case .denied, .restricted, .notDetermined:
// Use non-personalized ads
nonPersonalized = true
@unknown default:
nonPersonalized = true
}
// Initialize SDK after permission response
let config = EMAConfiguration(
appAdIdentifier: "YOUR_APP_AD_IDENTIFIER",
nonPersonalizedAds: nonPersonalized
)
EMAManager.shared.initialize(configuration: config)
}
}
} else {
// iOS 13 and earlier - no ATT required
let config = EMAConfiguration(appAdIdentifier: "YOUR_APP_AD_IDENTIFIER")
EMAManager.shared.initialize(configuration: config)
}
}

Don't forget to add the NSUserTrackingUsageDescription key to your Info.plist:

<key>NSUserTrackingUsageDescription</key>
<string>This app uses your data to provide personalized ads.</string>

Lifecycle Management

The SDK automatically manages ad lifecycle based on your app's state.

Background/Foreground Handling

The SDK automatically handles app state transitions. For custom behavior, you can hook into these events:

// In AppDelegate or SceneDelegate
func applicationDidEnterBackground(_ application: UIApplication) {
// SDK automatically pauses all ad refresh timers
// No action required
}
func applicationWillEnterForeground(_ application: UIApplication) {
// SDK automatically resumes ad refresh timers
// If app was in background for extended period,
// SDK will refresh ad configuration automatically
}

Disabling Ads for Premium Users

// Disable all ads for premium users
func userPurchasedPremium() {
EMASettings.shared.isAdsDisabled = true
// Destroy any currently loaded ads
// (they will automatically stop showing)
}
// Re-enable ads if subscription expires
func premiumSubscriptionExpired() {
EMASettings.shared.isAdsDisabled = false
}