Native Ads Advanced is currently in a limited beta release. If you are interested in participating, reach out to your account manager to discuss the possibility. This feature will be made available to all publishers at the conclusion of the beta.
Native Ads Advanced is a format in which ad assets are presented to users via UI components that are native to the platform. They're shown using the same classes you already use in your storyboards, and can be formatted to match your app's visual design. When an ad loads, your app receives an ad object that contains its assets, and the app (rather than the SDK) is then responsible for displaying them.
There are two system-defined formats for native
ads: app install and content.
App install ads are represented by
GADNativeAppInstallAd,
and content ads are represented by
GADNativeContentAd.
Instances of the classes contain the assets
for the native ad.
This guide shows you how to integrate Native Ads Advanced from AdMob into an iOS app.
Prerequisites
- Import the Google Mobile Ads SDK, either by itself or as part of Firebase.
Load an ad
Native Advanced ads are loaded via
GADAdLoader
objects, which send messages
to their delegates according to the
GADAdLoaderDelegate
protocol.
Initialize a GADAdLoader
The following code demonstrates how to initialize a GADAdLoader for an app
install ad:
Swift
adLoader = GADAdLoader(adUnitID: "ca-app-pub-3940256099942544/3986624511",
rootViewController: self,
adTypes: [ ... ad type constants ... ],
options: [ ... ad loader options objects ... ])
adLoader.delegate = self
Objective-C
self.adLoader = [[GADAdLoader alloc]
initWithAdUnitID:@"ca-app-pub-3940256099942544/3986624511"
rootViewController:rootViewController
adTypes:@[ ... ad type constants ... ]
options:@[ ... ad loader options objects ... ]];
self.adLoader.delegate = self;
The adTypes array parameter allows your app to pass in constants that specify
which native formats it wants to request. The array should contain one or both
of the following constants:
kGADAdLoaderAdTypeNativeAppInstallkGADAdLoaderAdTypeNativeContent
Request the ad
Once your
GADAdLoader
is initialized, call its
loadRequest:
method to request an ad:
Swift
adLoader.load(GADRequest())
Objective-C
[self.adLoader loadRequest:[GADRequest request]];
The loadRequest: method in GADAdLoader accepts the same
GADRequest
objects as banners and interstitials. You can use request objects to add
targeting information just as you would with other ad types.
A single GADAdLoader can make multiple requests, but only if they're done one
at a time. When reusing a GADAdLoader, make sure you wait for each request to
finish before calling loadRequest: again to begin the next. If you need to
request multiple ads in parallel, you can always use multiple GADAdLoader
objects.
GADAdLoaderDelegate protocols
For each ad format you request, the ad loader delegate needs to implement a corresponding protocol:
GADNativeAppInstallAdLoaderDelegate
This protocol includes a message that's sent to the delegate when an app install ad has loaded:
Swift
public func adLoader(_ adLoader: GADAdLoader,
didReceive nativeAppInstallAd: GADNativeAppInstallAd)
Objective-C
- (void)adLoader:(GADAdLoader *)adLoader
didReceiveNativeAppInstallAd:(GADNativeAppInstallAd *)nativeAppInstallAd;
GADNativeContentAdLoaderDelegate
This one defines a message sent when a content ad has loaded:
Swift
public func adLoader(_ adLoader: GADAdLoader,
didReceive nativeContentAd: GADNativeContentAd)
Objective-C
- (void)adLoader:(GADAdLoader *)adLoader
didReceiveNativeContentAd:(GADNativeContentAd *)nativeContentAd;
Handle a failed request
The above protocols extend the GADAdLoaderDelegate protocol, which defines a
message sent when ads fail to load:
Swift
public func adLoader(_ adLoader: GADAdLoader,
didFailToReceiveAdWithError error: GADRequestError)
Objective-C
- (void)adLoader:(GADAdLoader *)adLoader
didFailToReceiveAdWithError:(GADRequestError *)error;
You can use the GADRequestError object to determine the cause of the error.
Ad options
The last parameter included in the creation of the GADAdLoader above is an
optional array of objects:
Swift
adLoader =
GADAdLoader(adUnitID: "ca-app-pub-3940256099942544/3986624511",
rootViewController: self,
adTypes: [ ... ad type constants ... ],
options: [ ... ad loader options objects ... ])
Objective-C
self.adLoader = [[GADAdLoader alloc]
initWithAdUnitID:@"ca-app-pub-3940256099942544/3986624511"
rootViewController:rootViewController
adTypes:@[ ... ad type constants ... ]
options:@[ ... ad loader options objects ... ]];
This optional array holds one or more instances of a
GADAdLoaderOptions
subclass, objects that an app can use to indicate its preferences for how native
ads should be loaded and behave.
GADNativeAdImageAdLoaderOptions
GADNativeAdImageAdLoaderOptions
contains properties relating to images in
Native Advanced ads. Apps can control how a GADAdLoader handles Native Ads
Advanced image assets by creating a GADNativeAdImageAdLoaderOptions object,
setting its properties
(disableImageLoading,
preferredImageOrientation,
and
shouldRequestMultipleImages),
and passing it in during initialization.
disableImageLoading
Image assets for ads are returned via instances of
GADNativeAdImage,
which contains
image and
imageURL
properties. If disableImageLoading is set to false (default), the SDK
fetches image assets automatically and populates both the image and the
imageURL properties for you. If it's set to true, however, the SDK only
populates imageURL, allowing you to download the actual images at your
discretion.
preferredImageOrientation
Some creatives have multiple available images to match different device orientations. Apps can request images for a particular orientation by setting this property to one of the orientation constants:
GADNativeAdImageAdLoaderOptionsOrientationAnyGADNativeAdImageAdLoaderOptionsOrientationLandscapeGADNativeAdImageAdLoaderOptionsOrientationPortrait
If you use preferredImageOrientation to specify a preference for landscape or
portrait image orientation, the SDK places images matching that orientation
first in image asset arrays and place non-matching images after them. Since
some ads only have one orientation available, publishers should make sure that
their apps can handle both landscape and portrait images.
If this method is not called, the default value of
GADNativeAdImageAdLoaderOptionsOrientationAny is used.
shouldRequestMultipleImages
Some image assets contain a series of images rather than just one. By setting this value to true, your app indicates that it's prepared to display all the images for any assets that have more than one. By setting it to false (default) your app instructs the SDK to provide just the first image for any assets that contain a series.
If no GADAdLoaderOptions objects are passed in when initializing a
GADAdLoader, the default value for each option is used.
GADNativeAdViewOptions
GADNativeAdViewAdOptions
objects are used to indicate preferences for how native ad views should
represent ads. They have a single property:
preferredAdChoicesPosition.
This property indicates in which corner of the ad view the AdChoices attribution icon should appear. The possible values for this property are:
GADAdChoicesPositionTopRightCornerGADAdChoicesPositionTopLeftCornerGADAdChoicesPositionBottomRightCornerGADAdChoicesPositionBottomLeftCorner
GADVideoOptions
GADVideoOptions
objects are used to indicate how native video assets should be displayed. They
offer a single property:
startMuted.
This boolean indicates whether video assets should begin playback in a muted
state. The default value is true.
Always test with test ads
The sample code above contains an ad unit ID and you're free to request ads with it. It's been specially configured to return test ads rather than production ads for every request, which makes it safe to use.
However, once you register an app in the AdMob UI and create your own ad unit IDs for use in your app, you'll need to explicitly configure your device as a test device when you're developing. This is extremely important. Testing with real ads (even if you never tap on them) is against AdMob policy and can cause your account to be suspended. See Test Ads for information on how you can make sure you always get test ads when developing.
When to request ads
Applications displaying Native Advanced ads are free to request them in advance of when they'll actually be displayed. In many cases, this is the recommended practice. An app displaying a list of items with ads mixed in, for example, can load ads for the whole list, knowing that some are shown only after the user scrolls the view and some may not be displayed at all.
While prefetching ads is a great technique, it's important that publishers not keep old ads around forever without displaying them. Any native ad objects that have been held without display for longer than an hour should be discarded and replaced with new ads from a new request.
Display an ad
When an ad loads, your app receives an ad object via one of the
GADAdLoaderDelegate protocol messages. Your app is then responsible for
displaying the ad (though it doesn't necessarily have to do so immediately). To
make displaying system-defined ad formats easier, the SDK offers some useful
resources.
The ad view classes
For each of the system-defined formats, there is a corresponding "ad view"
class:
GADNativeAppInstallAdView
for app install ads, and
GADNativeContentAdView
for content ads. These ad view
classes are UIViews that publishers should use to display ads of the
corresponding format. A single GADNativeAppInstallAdView, for example, can
display a single instance of a GADNativeAppInstallAd. Each of the UIViews
used to display that ad's assets should be children of that
GADNativeAppInstallAdView object.
If you were displaying an app install ad in a UITableView, for example, the
view hierarchy for one of the cells might look like this:

The ad view classes also provide IBOutlets used to register the view used for
each individual asset, and a method to register the
GADNativeAd
object itself. Registering the views in this way allows the SDK to automatically
handle tasks such as:
- Recording clicks.
- Recording impressions (when the first pixel is visible on the screen).
- Displaying the AdChoices overlay.
The AdChoices overlay
An AdChoices overlay is added to each ad view by the SDK. Leave space in your preferred corner of your native ad view for the automatically inserted AdChoices logo. Also, it's important that the AdChoices overlay be easily seen, so choose background colors and images appropriately. For more information on the overlay's appearance and function, see Guidelines for programmatic native ads using native styles.
Code example
Let's take a look at how to display Native Advanced ads using views loaded
dynamically from xib files. This can be a very useful approach when using
GADAdLoaders configured to request multiple formats.
Lay out UIViews in the xib file
The first step is to lay out the UIViews for displaying native ad assets. You
can do this in the Interface Builder as you would when creating any other xib
file. Here's an example layout for an app install ad:

And here's an example layout for a content ad:

Note the Custom Class value at the top right of both of the images. It's set to
GADNativeAppInstallAdView and GADNativeContentAdView. These are the ad view
classes that are used to display a GADNativeAppInstallAd and a
GADNativeContentAd. For system-defined formats, use the ad view class that
matches the ad format you intend the layout to show.
Link the outlets to the views
Once the views are in place and you've assigned the correct ad view class to
the layout, link the ad view's asset outlets to the UIViews you've created.
Here's how you might link the ad view's asset outlets to the UIViews created
for an app install ad:

And here's how you might link the ad view's asset outlets to the UIViews
created for a content ad:

In the outlet panel, the outlets in GADNativeAppInstallAdView and
GADNativeContentAdView have been linked to the UIViews laid out in the
Interface Builder. This lets the SDK know which UIView displays which asset.
It's also important to remember that these outlets represent the views that are
clickable in the ad.
Display the ad
Once the layout is complete and the outlets are linked, the last step is to add code to your app that displays an ad once it has loaded. Here's a method to display an app install ad in the view defined above:
Swift
// Mark: - GADNativeAppInstallAdLoaderDelegate
func adLoader(_ adLoader: GADAdLoader,
didReceive nativeAppInstallAd: GADNativeAppInstallAd) {
// Create and place the ad in the view hierarchy.
let appInstallAdView = Bundle.main.loadNibNamed("NativeAppInstallAdView", owner: nil,
options: nil)?.first as! GADNativeAppInstallAdView
// TODO: Make sure to add the GADNativeAppInstallAdView to the view hierarchy.
// Associate the app install ad view with the app install ad object. This is required to make
// the ad clickable.
appInstallAdView.nativeAppInstallAd = nativeAppInstallAd
// Populate the app install ad view with the app install ad assets.
// Some assets are guaranteed to be present in every app install ad.
(appInstallAdView.headlineView as! UILabel).text = nativeAppInstallAd.headline
(appInstallAdView.iconView as! UIImageView).image = nativeAppInstallAd.icon?.image
(appInstallAdView.bodyView as! UILabel).text = nativeAppInstallAd.body
(appInstallAdView.imageView as! UIImageView).image =
(nativeAppInstallAd.images?.first as! GADNativeAdImage).image
(appInstallAdView.callToActionView as! UIButton).setTitle(
nativeAppInstallAd.callToAction, for: UIControlState.normal)
// Other assets are not, however, and should be checked first.
let starRatingView = appInstallAdView.starRatingView
if let starRating = nativeAppInstallAd.starRating {
(starRatingView as! UIImageView).image = imageOfStarsFromStarRating(starRating)
starRatingView?.isHidden = false
} else {
starRatingView?.isHidden = true
}
let storeView = appInstallAdView.storeView
if let store = nativeAppInstallAd.store {
(storeView as! UILabel).text = store
storeView?.isHidden = false
} else {
storeView?.isHidden = true
}
let priceView = appInstallAdView.priceView
if let price = nativeAppInstallAd.price {
(priceView as! UILabel).text = price
priceView?.isHidden = false
} else {
priceView?.isHidden = true
}
// In order for the SDK to process touch events properly, user interaction should be disabled on
// all views associated with the GADNativeAppInstallAdView. Since UIButton has
// userInteractionEnabled set to true by default, views of this type must explicitly set
// userInteractionEnabled to false.
(appInstallAdView.callToActionView as! UIButton).isUserInteractionEnabled = false
}
Objective-C
#pragma mark GADNativeAppInstallAdLoaderDelegate implementation
- (void)adLoader:(GADAdLoader *)adLoader
didReceiveNativeAppInstallAd:(GADNativeAppInstallAd *)nativeAppInstallAd {
// Create and place ad in view hierarchy.
GADNativeAppInstallAdView *appInstallAdView =
[[[NSBundle mainBundle] loadNibNamed:@"NativeAppInstallAdView"
owner:nil
options:nil] firstObject];
// TODO: Make sure to add the GADNativeAppInstallAdView to the view hierarchy.
// Associate the app install ad view with the app install ad object. This is required to make the
// ad clickable.
appInstallAdView.nativeAppInstallAd = nativeAppInstallAd;
// Populate the app install ad view with the app install ad assets.
// Some assets are guaranteed to be present in every app install ad.
((UILabel *)appInstallAdView.headlineView).text = nativeAppInstallAd.headline;
((UIImageView *)appInstallAdView.iconView).image = nativeAppInstallAd.icon.image;
((UILabel *)appInstallAdView.bodyView).text = nativeAppInstallAd.body;
((UIImageView *)appInstallAdView.imageView).image =
((GADNativeAdImage *)[nativeAppInstallAd.images firstObject]).image;
[((UIButton *)appInstallAdView.callToActionView)setTitle:nativeAppInstallAd.callToAction
forState:UIControlStateNormal];
// Other assets are not, however, and should be checked first.
if (nativeAppInstallAd.starRating) {
((UIImageView *)appInstallAdView.starRatingView).image =
[self imageForStars:nativeAppInstallAd.starRating];
appInstallAdView.starRatingView.hidden = NO;
} else {
appInstallAdView.starRatingView.hidden = YES;
}
if (nativeAppInstallAd.store) {
((UILabel *)appInstallAdView.storeView).text = nativeAppInstallAd.store;
appInstallAdView.storeView.hidden = NO;
} else {
appInstallAdView.storeView.hidden = YES;
}
if (nativeAppInstallAd.price) {
((UILabel *)appInstallAdView.priceView).text = nativeAppInstallAd.price;
appInstallAdView.priceView.hidden = NO;
} else {
appInstallAdView.priceView.hidden = YES;
}
// In order for the SDK to process touch events properly, user interaction should be disabled on
// all views associated with the GADNativeAppInstallAdView. Since UIButton has
// userInteractionEnabled set to YES by default, views of this type must explicitly set
// userInteractionEnabled to NO.
appInstallAdView.callToActionView.userInteractionEnabled = NO;
}
And here's a method to display a content ad in the view defined above:
Swift
// Mark: - GADNativeContentAdLoaderDelegate
func adLoader(_ adLoader: GADAdLoader,
didReceive nativeContentAd: GADNativeContentAd) {
// Create and place the ad in the view hierarchy.
let contentAdView = Bundle.main.loadNibNamed(
"NativeContentAdView", owner: nil, options: nil)?.first as! GADNativeContentAdView
// TODO: Make sure to add the GADNativeContentAdView to the view hierarchy.
// Associate the content ad view with the content ad object. This is required to make the ad
// clickable.
contentAdView.nativeContentAd = nativeContentAd
// Populate the content ad view with the content ad assets.
// Some assets are guaranteed to be present in every content ad.
(contentAdView.headlineView as! UILabel).text = nativeContentAd.headline
(contentAdView.bodyView as! UILabel).text = nativeContentAd.body
(contentAdView.imageView as! UIImageView).image =
(nativeContentAd.images?.first as! GADNativeAdImage).image
(contentAdView.advertiserView as! UILabel).text = nativeContentAd.advertiser
(contentAdView.callToActionView as! UIButton).setTitle(
nativeContentAd.callToAction, for: UIControlState.normal)
// Other assets are not, however, and should be checked first.
let logoView = contentAdView.logoView
if let logoImage = nativeContentAd.logo?.image {
(logoView as! UIImageView).image = logoImage
logoView?.isHidden = false
} else {
logoView?.isHidden = true
}
// In order for the SDK to process touch events properly, user interaction should be disabled on
// all views associated with the GADNativeContentAdView. Since UIButton has userInteractionEnabled
// set to true by default, views of this type must explicitly set userInteractionEnabled to false.
(contentAdView.callToActionView as! UIButton).isUserInteractionEnabled = false
}
Objective-C
#pragma mark GADNativeContentAdLoaderDelegate implementation
- (void)adLoader:(GADAdLoader *)adLoader
didReceiveNativeContentAd:(GADNativeContentAd *)nativeContentAd {
// Create and place ad in view hierarchy.
GADNativeContentAdView *contentAdView =
[[[NSBundle mainBundle] loadNibNamed:@"NativeContentAdView"
owner:nil
options:nil] firstObject];
// TODO: Make sure to add the GADNativeContentAdView to the view hierarchy.
// Associate the content ad view with the content ad object. This is required to make the ad
// clickable.
contentAdView.nativeContentAd = nativeContentAd;
// Populate the content ad view with the content ad assets.
// Some assets are guaranteed to be present in every content ad.
((UILabel *)contentAdView.headlineView).text = nativeContentAd.headline;
((UILabel *)contentAdView.bodyView).text = nativeContentAd.body;
((UIImageView *)contentAdView.imageView).image =
((GADNativeAdImage *)[nativeContentAd.images firstObject]).image;
((UILabel *)contentAdView.advertiserView).text = nativeContentAd.advertiser;
[((UIButton *)contentAdView.callToActionView)setTitle:nativeContentAd.callToAction
forState:UIControlStateNormal];
// Other assets are not, however, and should be checked first.
if (nativeContentAd.logo && nativeContentAd.logo.image) {
((UIImageView *)contentAdView.logoView).image = nativeContentAd.logo.image;
contentAdView.logoView.hidden = NO;
} else {
contentAdView.logoView.hidden = YES;
}
// In order for the SDK to process touch events properly, user interaction should be disabled on
// all views associated with the GADNativeContentAdView. Since UIButton has userInteractionEnabled
// set to YES by default, views of this type must explicitly set userInteractionEnabled to NO.
contentAdView.callToActionView.userInteractionEnabled = NO;
}
As you can see, the code examples above disable user interaction for the UIButton that displays the call to action. If you use UIButtons to display native ad assets, you also need to disable their user interaction so that the Google Mobile Ads SDK can properly receive and process UI events. Because of this extra step, it's frequently best to avoid UIButtons entirely and use UILabel and UIImageView instead.
Native video
In addition to images, text, and numbers, some native ads contain video assets. Not every ad will have one and apps are not required to display videos when they're included with an ad.
GADMediaView
Video assets are displayed to users via
GADMediaView. This is a
UIView that can be defined in a nib file or constructed dynamically. It
should be placed within the view hierarchy of a GADNativeAdView, as with any
other asset view.
Unlike other asset views, however, apps do not need to manually populate a
GADMediaView with its asset. The SDK handles this automatically as follows:
- If a video asset is available, it is buffered and starts
playing inside the
GADMediaView. - If the ad does not contain a video asset, the first image
asset is downloaded and placed inside the
GADMediaViewinstead.
While apps that don't intend to display video assets aren't required to include
a GADMediaView in their layouts, it's recommended that they do.
GADVideoController
The GADVideoController
class is used to retrieve information about video assets. GADNativeAppInstallAd
and GADNativeContentAd both offer a
videoController
property that exposes the GADVideoController for each ad:
Swift
let vc1 = myAppInstallAd.videoController let vc2 = myContentAd.videoController
Objective-C
GADVideoController *vc1 = myAppInstallAd.videoController GADVideoController *vc2 = myContentAd.videoController
This property is never nil, even when the ad doesn't contain a video asset.
GADVideoController offers the following methods for querying video state:
hasVideoContent- True if the ad includes a video asset, false otherwise.aspectRatio- The aspect ratio of the video (width/height) or zero (if no video asset is present).
Apps can also set a
GADViewControllerDelegate
for the GADViewController to be notified of events in the lifecycle of a
video asset. GADViewControllerDelegate offers a single optional message,
videoControllerDidEndVideoPlayback,
which is sent when a video completes playback.
Here's an example of GADViewControllerDelegate in action:
Swift
class ViewController: UIViewController, GADNativeAppInstallAdLoaderDelegate,
GADVideoControllerDelegate
func adLoader(_ adLoader: GADAdLoader, didReceive nativeAppInstallAd:
GADNativeAppInstallAd) {
...
nativeAppInstallAd.videController.delegate = self
...
}
...
func videoControllerDidEndVideoPlayback(_ videoController: Any!) {
// Here apps can take action knowing video playback is finished.
// This is handy for things like unmuting audio, and so on.
}
}
Objective-C
@interface ViewController ()- (void)adLoader:(GADAdLoader *)adLoader didReceiveNativeAppInstallAd:(GADNativeAppInstallAd) *)nativeAppInstallAd { ... nativeAppInstallAd.videoController.delegate = self; ... } ... - (void)videoControllerDidEndVideoPlayback:(GADVideoController *)videoController { // Here apps can take action knowing video playback is finished. // This is handy for things like unmuting audio, and so on. } @end
Additional resources
Samples
- Native Ads Advanced sample on GitHub: Swift | Objective-C
Codelab
Next steps
- Learn about Ad Events and Ad Targeting.
- Try another ad format: