Banner Ads
Banner ads are rectangular ads that occupy a portion of your app's layout. They can refresh automatically and stay on screen while users interact with your app.
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 EmpowerMobileAdsclass ViewController: UIViewController, AdStatusDelegate {@IBOutlet weak var bannerContainer: UIView!override func viewWillAppear(_ animated: Bool) {super.viewWillAppear(animated)loadBanner()}func loadBanner() {EMAManager.shared.loadBannerAd(viewController: self,zoneId: "YOUR_BANNER_ZONE_ID",bannerContainer: bannerContainer,delegate: self)}func bannerStatusChanged(_ manager: EmpowerBannerManager) {switch manager.status {case .ready:print("Banner is ready and displayed")case .failed:print("Banner failed to load")case .initializing:print("Banner is loading...")default:break}}}
Supported Sizes
| Size | Description |
|---|---|
| 320x50 | Standard Banner |
| 320x100 | Large Banner |
| 300x250 | Medium Rectangle |
Container Setup
Interface Builder (Storyboard)
- Add a
UIViewto your view controller - Set constraints for position and height
- Connect the outlet to your view controller
Programmatic Setup
// Standard Banner (320x50)let bannerContainer = UIView()bannerContainer.translatesAutoresizingMaskIntoConstraints = falseview.addSubview(bannerContainer)NSLayoutConstraint.activate([bannerContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor),bannerContainer.trailingAnchor.constraint(equalTo: view.trailingAnchor),bannerContainer.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),bannerContainer.heightAnchor.constraint(equalToConstant: 50)])
// MREC (300x250)let mrecContainer = UIView()mrecContainer.translatesAutoresizingMaskIntoConstraints = falseview.addSubview(mrecContainer)NSLayoutConstraint.activate([mrecContainer.centerXAnchor.constraint(equalTo: view.centerXAnchor),mrecContainer.topAnchor.constraint(equalTo: someView.bottomAnchor, constant: 16),mrecContainer.widthAnchor.constraint(equalToConstant: 300),mrecContainer.heightAnchor.constraint(equalToConstant: 250)])
Loading Options
Basic Loading
EMAManager.shared.loadBannerAd(viewController: self,zoneId: "YOUR_ZONE_ID",bannerContainer: bannerContainer,delegate: self)
With Keywords
EMAManager.shared.loadBannerAd(viewController: self,zoneId: "YOUR_ZONE_ID",bannerContainer: bannerContainer,delegate: self,keywords: "sports,football,news")
With Custom Parameters
let customParams: [String: [String]] = ["article_id": ["12345"],"section": ["sports"],"author": ["john_doe"]]EMAManager.shared.loadBannerAd(viewController: self,zoneId: "YOUR_ZONE_ID",bannerContainer: bannerContainer,delegate: self,adConfiguration: nil,customParameters: customParams,category: "sports")
Status Handling
AdStatusDelegate
extension ViewController: AdStatusDelegate {func bannerStatusChanged(_ manager: EmpowerBannerManager) {let zoneId = manager.bannerModel?.adConstraints.zoneId ?? ""switch manager.status {case .initializing:// Banner is loadingshowLoadingIndicator()case .ready:// Banner is displayedhideLoadingIndicator()print("Banner loaded for zone: \(zoneId)")case .failed:// Banner failed to loadhideLoadingIndicator()hideBannerContainer()print("Banner failed for zone: \(zoneId)")default:break}}// Optional: Track loading progressfunc bannerLoadingProgress(loaded: Int, total: Int, fastestAdId: String?) {print("Loading: \(loaded)/\(total) ad sources")}}
Status Values
| Status | Description |
|---|---|
.initializing | Banner is loading |
.ready | Banner is displayed |
.failed | Banner failed to load |
.undefined | Initial/destroyed state |
SwiftUI Integration
import SwiftUIimport EmpowerMobileAds// MARK: - Banner Viewstruct BannerAdView: UIViewControllerRepresentable {let zoneId: Stringlet height: CGFloatfunc makeUIViewController(context: Context) -> BannerAdViewController {return BannerAdViewController(zoneId: zoneId)}func updateUIViewController(_ uiViewController: BannerAdViewController, context: Context) {}}// MARK: - Banner View Controllerclass BannerAdViewController: UIViewController, AdStatusDelegate {private let zoneId: Stringprivate var bannerContainer: UIView!init(zoneId: String) {self.zoneId = zoneIdsuper.init(nibName: nil, bundle: nil)}required init?(coder: NSCoder) {fatalError("init(coder:) has not been implemented")}override func viewDidLoad() {super.viewDidLoad()setupContainer()loadBanner()}private func setupContainer() {bannerContainer = UIView()bannerContainer.translatesAutoresizingMaskIntoConstraints = falseview.addSubview(bannerContainer)NSLayoutConstraint.activate([bannerContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor),bannerContainer.trailingAnchor.constraint(equalTo: view.trailingAnchor),bannerContainer.topAnchor.constraint(equalTo: view.topAnchor),bannerContainer.bottomAnchor.constraint(equalTo: view.bottomAnchor)])}private func loadBanner() {EMAManager.shared.loadBannerAd(viewController: self,zoneId: zoneId,bannerContainer: bannerContainer,delegate: self)}func bannerStatusChanged(_ manager: EmpowerBannerManager) {// Handle status changes}}// MARK: - Usagestruct ContentView: View {var body: some View {VStack {Text("Your Content")Spacer()// Standard BannerBannerAdView(zoneId: "YOUR_BANNER_ZONE_ID", height: 50).frame(height: 50)}}}struct ArticleView: View {var body: some View {ScrollView {VStack {Text("Article Title").font(.title)// MREC in contentBannerAdView(zoneId: "YOUR_MREC_ZONE_ID", height: 250).frame(height: 250)Text("Article content...")}}}}
Lifecycle Management
Visibility Handling
override func viewWillAppear(_ animated: Bool) {super.viewWillAppear(animated)// Resume banner refresh timerEMAManager.shared.visible(viewController: self)}override func viewWillDisappear(_ animated: Bool) {super.viewWillDisappear(animated)// Destroy banner if leaving permanentlyif isMovingFromParent || isBeingDismissed {EMAManager.shared.destroy(controllerIdentifier: self.hash)}}
Tab Bar Navigation
When using tab bar controllers, banners automatically pause on inactive tabs:
class TabBarController: UITabBarController, UITabBarControllerDelegate {override func viewDidLoad() {super.viewDidLoad()delegate = self}func tabBarController(_ tabBarController: UITabBarController,didSelect viewController: UIViewController) {// Notify SDK of visible tabEMAManager.shared.visible(viewController: viewController)}}
Auto-Refresh
Banner ads automatically refresh based on server configuration. The SDK handles:
- Pausing refresh when view is not visible
- Pausing refresh when app is in background
- Resuming refresh when view becomes visible again
You don't need to manually reload banners for refresh - it's automatic.
Best Practices
1. Container Size
Always set explicit height constraints:
// GoodbannerContainer.heightAnchor.constraint(equalToConstant: 50).isActive = true// Avoid - may cause layout issuesbannerContainer.heightAnchor.constraint(greaterThanOrEqualToConstant: 50).isActive = true
2. Safe Area
Position banners within safe area:
// Good - respects safe areabannerContainer.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)// Avoid - may overlap with home indicatorbannerContainer.bottomAnchor.constraint(equalTo: view.bottomAnchor)
3. Load in viewWillAppear
override func viewWillAppear(_ animated: Bool) {super.viewWillAppear(animated)loadBanner() // Load when view is about to appear}
4. Handle Failures Gracefully
func bannerStatusChanged(_ manager: EmpowerBannerManager) {if manager.status == .failed {// Option 1: Hide containerbannerContainer.isHidden = true// Option 2: Show fallback contentshowFallbackContent()// Option 3: Collapse container heightbannerHeightConstraint.constant = 0UIView.animate(withDuration: 0.3) {self.view.layoutIfNeeded()}}}
Troubleshooting
Banner Not Showing
- Check container visibility:
print("Hidden: \(bannerContainer.isHidden)")print("Alpha: \(bannerContainer.alpha)")print("Frame: \(bannerContainer.frame)")
- Check container is in view hierarchy:
print("Superview: \(bannerContainer.superview)")
Check zone ID is correct
Enable debug logging:
EMASettings.shared.logLevel = .all
Banner Loading Slowly
The SDK loads ads from multiple sources in parallel and selects the best one. This optimization may take a moment. You can show a placeholder:
func bannerStatusChanged(_ manager: EmpowerBannerManager) {switch manager.status {case .initializing:showPlaceholder()case .ready:hidePlaceholder()default:break}}
API Reference
EMAManager.loadBannerAd
func loadBannerAd(viewController: UIViewController,zoneId: String,bannerContainer: UIView,delegate: AdStatusDelegate?,adConfiguration: AdConfiguration? = nil,customParameters: [String: [String]]? = nil,category: String? = nil,keywords: String? = nil) -> EmpowerZoneManager?
| Parameter | Type | Description |
|---|---|---|
viewController | UIViewController | The hosting view controller |
zoneId | String | Your banner zone ID |
bannerContainer | UIView | Container view for the banner |
delegate | AdStatusDelegate? | Callback delegate |
customParameters | [String: [String]]? | Custom targeting parameters |
category | String? | Content category |
keywords | String? | Targeting keywords |
Returns: EmpowerZoneManager? - Manager instance for lifecycle control