This feature 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.
This guide shows you how to use the Google Mobile Ads SDK to implement AdMob Native Ads Advanced in an iOS app as well as some important things to consider along the way.
Prerequisites
This guide assumes some working knowledge of the Google Mobile Ads SDK. If you haven't already done so, see Get Started.
What's Native Ads Advanced?
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.
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:
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;
Swift
adLoader = GADAdLoader(adUnitID: "ca-app-pub-3940256099942544/3986624511", rootViewController: self, adTypes: [ ... ad type constants ... ], options: [ ... ad loader options objects ... ]) 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:
- kGADAdLoaderAdTypeNativeAppInstall
- kGADAdLoaderAdTypeNativeContent
Request the ad
Once your GADAdLoader
is initialized,
call its loadRequest:()
method to request an ad:
Objective-C
[self.adLoader loadRequest:[GADRequest request]];
Swift
adLoader.loadRequest(GADRequest())
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:
Objective-C
- (void)adLoader:(GADAdLoader *)adLoader didReceiveNativeAppInstallAd:(GADNativeAppInstallAd *)nativeAppInstallAd;
Swift
public func adLoader(adLoader: GADAdLoader!, didReceiveNativeAppInstallAd nativeAppInstallAd: GADNativeAppInstallAd!)
GADNativeContentAdLoaderDelegate
This one defines a message sent when a content ad has loaded:
Objective-C
- (void)adLoader:(GADAdLoader *)adLoader didReceiveNativeContentAd:(GADNativeContentAd *)nativeContentAd;
Swift
public func adLoader(adLoader: GADAdLoader!, didReceiveNativeContentAd nativeContentAd: GADNativeContentAd!)
Handle a failed request
The above protocols extend the GADAdLoaderDelegate
protocol,
which defines a message sent when ads fail to load:
Objective-C
- (void)adLoader:(GADAdLoader *)adLoader didFailToReceiveAdWithError:(GADRequestError *)error;
Swift
public func adLoader(adLoader: GADAdLoader!, didFailToReceiveAdWithError error: GADRequestError!)
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:
Objective-C
self.adLoader = [[GADAdLoader alloc] initWithAdUnitID:@"/6499/example/native" rootViewController:rootViewController adTypes:@[ ... ad type constants ... ] options:@[ ... ad loader options objects ... ]];
Swift
adLoader = GADAdLoader(adUnitID: "/6499/example/native", rootViewController: self, adTypes: [ ... ad type constants ... ], options: [ ... ad loader options objects ... ])
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,
and passing it in during initialization.
GADNativeAdImageAdLoaderOptions
has the following properties:
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 populate 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:
- GADNativeAdImageAdLoaderOptionsOrientationAny
- GADNativeAdImageAdLoaderOptionsOrientationLandscape
- GADNativeAdImageAdLoaderOptionsOrientationPortrait
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.
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. Please leave space in the upper right 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 the native backfill implementation guidelines.
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 how the layout for an app install ad might look:
And here's how the layout for a content ad might look:
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:
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; }
Swift
// Mark: - GADNativeAppInstallAdLoaderDelegate func adLoader(adLoader: GADAdLoader!, didReceiveNativeAppInstallAd nativeAppInstallAd: GADNativeAppInstallAd!) { // Create and place the ad in the view hierarchy. let appInstallAdView = NSBundle.mainBundle().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, forState: 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.hidden = false } else { starRatingView.hidden = true } let storeView = appInstallAdView.storeView if let store = nativeAppInstallAd.store { (storeView as! UILabel).text = store storeView.hidden = false } else { storeView.hidden = true } let priceView = appInstallAdView.priceView if let price = nativeAppInstallAd.price { (priceView as! UILabel).text = price priceView.hidden = false } else { priceView.hidden = 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).userInteractionEnabled = false }
And here's a method to display a content ad in the view defined above:
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; }
Swift
// Mark: - GADNativeContentAdLoaderDelegate func adLoader(adLoader: GADAdLoader!, didReceiveNativeContentAd nativeContentAd: GADNativeContentAd!) { // Create and place the ad in the view hierarchy. let contentAdView = NSBundle.mainBundle().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, forState: 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.hidden = false } else { logoView.hidden = 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).userInteractionEnabled = false }
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.
Our GitHub repository has the complete implementations for Native Advanced app install ads and content ads written in both Swift and Objective-C.
Download Native Advanced Example
Testing your code
To help publishers test their implementations, we've made the following AdMob ad unit ID available for use:
ca-app-pub-3940256099942544/3986624511
Any requests you make to that ad unit are considered "test" requests and are not counted against production statistics.