Display Google AdMob banner ads in an iOS app using GADBannerView from the Google Mobile Ads SDK. Install the SDK via CocoaPods, initialize GADMobileAds in AppDelegate, create a GADBannerView with an adaptive ad size, assign your Ad Unit ID, call load(_:) with a GADRequest, and implement GADBannerViewDelegate to insert the banner into your view hierarchy. Interstitial ads use GADInterstitialAd with a separate Ad Unit ID and present full-screen through GADFullScreenContentDelegate.
Install the Google Mobile Ads SDK with CocoaPods
Create a Podfile in your project directory and add the Google-Mobile-Ads-SDK pod.
target 'YourApp' do
pod 'Google-Mobile-Ads-SDK'
end
Run pod install in the terminal. Always open the .xcworkspace file after installation. CocoaPods version 1.12 or later is required for the current SDK.
Initialize GADMobileAds in AppDelegate
Import GoogleMobileAds and call start(completionHandler:) in application(_:didFinishLaunchingWithOptions:).
import GoogleMobileAds
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
GADMobileAds.sharedInstance().start(completionHandler: nil)
return true
}
Early initialization loads ad configuration and prepares the device for ad requests. The completion handler fires when initialization completes.
Configure Info.plist with App ID and SKAdNetworkItems
Add the GADApplicationIdentifier key with your AdMob App ID as the value. The format is ca-app-pub-XXXXXXXXXXXX~XXXXXXXXXX.
Add the SKAdNetworkItems array with Google's ad network identifiers. Google publishes a list of SKAdNetworkIdentifier entries that changes over time. Reference the current Google Mobile Ads SDK documentation for the complete list. Missing entries prevent ad attribution on iOS 14 and later.
Create a GADBannerView with an Adaptive Ad Size
Use GADPortraitAnchoredAdaptiveBannerAdSizeWithWidth(_:) for a banner that automatically fits the device width.
lazy var bannerView: GADBannerView = {
let banner = GADBannerView(
adSize: GADPortraitAnchoredAdaptiveBannerAdSizeWithWidth(view.frame.width)
)
banner.adUnitID = "ca-app-pub-3940256099942544/2934735716"
banner.delegate = self
banner.rootViewController = self
return banner
}()
The demo Ad Unit ID ca-app-pub-3940256099942544/2934735716 is safe for development. Replace it with your own Ad Unit ID from the AdMob dashboard before release. Adaptive banners detect the device width and return the optimal ad size, eliminating device-specific layout code.
Use Lazy Initialization for the Banner View
The lazy keyword defers banner creation until the first access. This ensures self is available for the rootViewController assignment.
override func viewDidLoad() {
super.viewDidLoad()
bannerView.load(GADRequest())
}
Without lazy initialization, you would need to create the banner in viewDidLoad and assign rootViewController manually. The lazy closure is cleaner and groups all configuration in one place.
Load and Display the Banner Ad
Call load(_:) with a GADRequest to fetch an ad. Implement GADBannerViewDelegate to insert the banner into the view when it arrives.
extension ViewController: GADBannerViewDelegate {
func bannerViewDidReceiveAd(_ bannerView: GADBannerView) {
bannerView.frame.size.height = bannerView.adSize.size.height
tableView.tableHeaderView = bannerView
}
func bannerView(_ bannerView: GADBannerView,
didFailToReceiveAdWithError error: Error) {
print("Ad failed: (error.localizedDescription)")
}
}
Set the banner frame height to the ad size height before adding it to the table header. The tableView.tableHeaderView assignment positions the banner at the top of the scrollable content.
Add a Slide-Down Animation for the Banner
Animate the banner into view with a smooth slide-down effect.
func bannerViewDidReceiveAd(_ bannerView: GADBannerView) {
bannerView.transform = CGAffineTransform(translationX: 0, y: -bannerView.frame.height)
UIView.animate(withDuration: 0.5) {
bannerView.transform = .identity
self.tableView.tableHeaderView = bannerView
}
}
The translate transform moves the banner above the visible area. The identity transform animates it back to its natural position.
Make the Banner Sticky with Section Headers
Replace the table header view with a section header to keep the banner visible during scrolling.
override func tableView(_ tableView: UITableView,
viewForHeaderInSection section: Int) -> UIView? {
return bannerView
}
override func tableView(_ tableView: UITableView,
heightForHeaderInSection section: Int) -> CGFloat {
return bannerView.frame.height
}
Section headers remain pinned to the top of the table view during scrolling. Remove the tableView.tableHeaderView assignment from the delegate method when using this approach.
Implement GADInterstitialAd for Full-Screen Ads
Declare a GADInterstitialAd variable and load it with a separate Ad Unit ID.
var interstitial: GADInterstitialAd?
private func loadInterstitial() {
let request = GADRequest()
GADInterstitialAd.load(withAdUnitID: "ca-app-pub-3940256099942544/4411468910",
request: request) { ad, error in
self.interstitial = ad
self.interstitial?.fullScreenContentDelegate = self
}
}
extension ViewController: GADFullScreenContentDelegate {
func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
loadInterstitial() // Load the next interstitial
}
}
Call loadInterstitial() before presenting the ad. GADInterstitialAd is one-time use. Reload it in adDidDismissFullScreenContent to prepare the next impression.
Set Test Devices to Avoid Policy Violations
Configure test device identifiers to prevent accidental live ad serving during development.
GADMobileAds.sharedInstance().requestConfiguration.testDeviceIdentifiers = [GADSimulatorID]
Use GADSimulatorID for simulator testing. Add your physical device's advertising identifier for real device testing. Testing with live ads when you never tap them violates AdMob policy.
Best Practices for AdMob Integration
Use Google's demo Ad Unit IDs during development. Register test devices in requestConfiguration. Place banner ads at the top or bottom of the screen for minimal user disruption. Limit interstitial ads to natural break points such as between levels or after article completion. Handle ad load failures gracefully by logging the error and continuing without blocking app functionality. Keep the SKAdNetworkItems array up to date with Google's published identifiers. Set ad refresh intervals to 30 to 60 seconds for banners. Test on physical devices because ad behavior differs between simulator and real hardware.
Summary
This tutorial covered the complete implementation process from setup to working code. You now have a functional implementation that you can extend and customize for your own projects. The same patterns apply to related features in the iOS ecosystem.
Frequently Asked Questions
Can I test this on the iOS Simulator? Some features require a physical device with a compatible processor. The article notes specific sections where the Simulator is sufficient and where a real device is required.
Do I need an Apple Developer Program membership to use this? Testing on a physical device requires a free Apple Developer account. Publishing to the App Store requires a paid Apple Developer Program membership.
What iOS version is required? This tutorial targets iOS 14. Most of the APIs shown work on earlier versions as well, but some newer APIs may require the version specified in the article.
What are the prerequisites for this tutorial? You need Xcode installed on a Mac and basic familiarity with Swift programming. No prior experience with the specific framework is required.