Skip to main content

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
privacyModeEMAPrivacyMode.automaticGDPR / consent mode: .automatic, .nonPersonalized, or .manual (see GDPR Compliance)
extString""Optional external parameter
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(privacyMode: .nonPersonalized)
.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"
// 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

Recommended: use the default .automatic mode. When you don't set privacyMode (or set it to .automatic), the SDK runs the Google UMP / GDPR consent flow and the ATT prompt for you and applies the result to every ad request — you write no consent code. This is the right choice for most apps.

// Automatic consent — privacyMode defaults to .automatic, nothing else to do.
let config = EMAConfiguration(appAdIdentifier: "YOUR_APP_AD_IDENTIFIER")
EMAManager.shared.initialize(configuration: config)

Use the options below only to override the automatic behavior — force non-personalized ads (.nonPersonalized), or take full manual control of consent and ATT (.manual):

// Option 1: Use GDPR-compliant configuration
let config = EMAConfiguration.gdprCompliant(appAdIdentifier: "YOUR_APP_AD_IDENTIFIER")
EMAManager.shared.initialize(configuration: config)

// Option 2: Set the privacy mode explicitly
let config = EMAConfiguration(
appAdIdentifier: "YOUR_APP_AD_IDENTIFIER",
privacyMode: .nonPersonalized
)
EMAManager.shared.initialize(configuration: config)

// Option 3: At runtime based on user consent
EMASettings.shared.isAdsNonPersonalized = !userHasGivenConsent

App Tracking Transparency (iOS 14+)

In .automatic and .nonPersonalized privacy modes the SDK requests ATT automatically (after the UMP consent flow) and applies the result to ad requests for you — you do not call requestTrackingAuthorization yourself. You only need to declare NSUserTrackingUsageDescription in your Info.plist (see below), or the app crashes when the prompt is presented.

Only in .manual privacy mode do you drive ATT yourself. The example below shows that manual flow:

import AppTrackingTransparency
import EmpowerMobileAds

// Manual privacy mode: your app owns ATT (and any UMP/GDPR flow).
// In .manual mode the SDK does NOT auto-request ATT, so there is no double prompt.
func requestTrackingPermissionAndInitSDK() {
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { status in
DispatchQueue.main.async {
// Personalized ads only when the user authorized tracking.
EMASettings.shared.isAdsNonPersonalized = (status != .authorized)

let config = EMAConfiguration(
appAdIdentifier: "YOUR_APP_AD_IDENTIFIER",
privacyMode: .manual
)
EMAManager.shared.initialize(configuration: config)
}
}
} else {
// iOS 13 and earlier - no ATT prompt.
let config = EMAConfiguration(
appAdIdentifier: "YOUR_APP_AD_IDENTIFIER",
privacyMode: .manual
)
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
}