This feature is currently in beta release to a limited group of publishers.
This guide will show you how to use the Google Mobile Ads SDK to implement DFP native ads in an iOS application, 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, consider running through our Get Started guide.
What's a native ad?
Native ads are advertisements 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 a native ad loads, your app will receive a native ad object that contains its assets, and the app (rather than the SDK) is then responsible for displaying them.
System-defined native ad formats
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.
Native ads for both system-defined formats can be received from AdX backfill, which carries some additional requirements: certain assets must be displayed and the ad must be clearly differentiated from content. See the native backfill guidelines for more detail:
Custom native ad formats
In addition to the system-defined native formats,
DFP publishers have the option of creating their own native ad formats
by defining custom lists of assets.
These are called
custom native ad formats,
and can be used for direct-sold native ads.
Custom native ad formats enable publishers
to pass arbitrary structured data to their apps.
These ads are represented by the GADNativeCustomTemplateAd
class.
Custom native ad formats are also referred to as custom template ads. This is because publishers define their own "templates" (lists of asset names and types) for their custom native ad formats. This will become clearer as you progress through the guide, but for right now just remember that "custom template ads" and "custom native ad formats" both refer to the same kind of ad.
Loading system-defined native ad formats
Native ads are loaded via GADAdLoader
objects,
which send messages to their delegates
according to the GADAdLoaderDelegate
protocol.
Initializing a GADAdLoader
The following code demonstrates how to initialize a GADAdLoader
for an app install ad:
self.adLoader = [[GADAdLoader alloc]
initWithAdUnitID:@"/6499/example/native"
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 more of the following constants:
kGADAdLoaderAdTypeNativeAppInstall
kGADAdLoaderAdTypeNativeContent
kGADAdLoaderAdTypeNativeCustomTemplate
Requesting the native ad
Once your GADAdLoader
is initialized,
call its loadRequest:
method to request an ad:
[self.adLoader loadRequest:[DFPRequest request]];
GADAdLoaderDelegate protocols
For each native 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:
- (void)didReceiveNativeAppInstallAd:(GADNativeAppInstallAd *)nativeAppInstallAd;
GADNativeContentAdLoaderDelegate
This one defines a message sent when a content ad has loaded:
- (void)didReceiveNativeContentAd:(GADNativeContentAd *)nativeContentAd;
Handling a failed request
The above protocols extend the GADAdLoaderDelegate
protocol,
which defines a message sent when ads fail to load:
- (void)adLoader:(GADAdLoader *)adLoader didFailToReceiveAdWithError:(GADRequestError *)error;
You can use the GADRequestError
object
to determine the cause of the error.
Native ad options
The last parameter included in the creation of the GADAdLoader
above
is an optional array of objects:
self.adLoader = [[GADAdLoader alloc] initWithAdUnitID:@"/6499/example/native" rootViewController:rootViewController adTypes:@[ ... ad type constants ... ] options:@[ ... ad loader options objects ... ]];
GADNativeAdImageAdLoaderOptions
contains properties relating to images in native ads.
Apps can control how a GADAdLoader
handles native ad 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 native ads are returned via instances of GADNativeAdImage
,
which contains image
and imageURL
properties.
If disableImageLoading
is set to false
(default),
the SDK will fetch image assets automatically
and populate both the image
and the imageURL
properties for you.
If it's set to true,
however,
the SDK will only populate 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
will be used.
shouldRequestMultipleImages - Some image assets will 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 will be used.
When to request ads
Applications displaying native 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 native ads mixed in, for example, can load native ads for the whole list, knowing that some will be 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.
Displaying a system-defined native ad format
When a native ad loads,
your app will receive a native 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 native ads
of the corresponding format.
A single GADNativeAppInstallAdView
,
for example,
can display a single instance of a GADNativeAppInstallAd
.
Each UIView
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 and native ad object in this way
allows the SDK to handle a number of tasks automatically
(such as recording impressions and clicks,
as well as displaying the AdChoices overlay for native backfill creatives).
The AdChoices overlay
For indirect native ads (delivered via DFP backfill or through Ad Exchange or AdSense), an AdChoices overlay is added by the SDK. Please leave space in the upper right corner of your native ad view for the automatically inserted AdChoices logo. Also, make sure the AdChoices overlay is placed on content that allows the icon to be easily seen. 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 ads
using views loaded dynamically from xib files.
This can be a very useful approach
when using GADAdLoaders
configured to request multiple formats.
Laying out UIViews in the xib file
The first step is to lay out the UIViews
that will display 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:
Note the Custom Class value in the top right.
It's set to GADNativeAppInstallAdView
,
the ad view class that is used to display a GADNativeAppInstallAd
.
For system-defined formats,
you'll need to use the ad view class that matches
the ad format you intend the layout to show.
Linking the outlets to the views
Once the views are in place
and you've assigned the correct ad view class to the layout,
you need to link the ad view's asset outlets
to the UIViews
you've created:
In the outlet panel,
each GADNativeAppInstallAdView
outlet
is linked to a UIView
laid out in the Interface Builder.
This lets the SDK know which UIView
displays which asset.
Displaying 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:
- (void)adLoader:(GADAdLoader *)adLoader
didReceiveNativeAppInstallAd:(GADNativeAppInstallAd *)nativeAppInstallAd {
// Create a new AdView instance from the xib file
GADNativeAppInstallAdView *appInstallAdView =
[[[NSBundle mainBundle] loadNibNamed:@"NativeAppInstallAdView"
owner:nil
options:nil] firstObject];
// 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.
((UILabel *)appInstallAdView.headlineView).text = nativeAppInstallAd.headline;
[((UIButton *)appInstallAdView.callToActionView)
setTitle:nativeAppInstallAd.callToAction
forState:UIControlStateNormal];
((UIImageView *)appInstallAdView.iconView).image = nativeAppInstallAd.icon.image;
((UILabel *)appInstallAdView.bodyView).text = nativeAppInstallAd.body;
((UILabel *)appInstallAdView.storeView).text = nativeAppInstallAd.store;
((UILabel *)appInstallAdView.priceView).text = nativeAppInstallAd.price;
((UIImageView *)appInstallAdView.imageView).image =
((GADNativeAdImage *)[nativeAppInstallAd.images firstObject]).image;
((UIImageView *)appInstallAdView.starRatingView).image =
[self imageForStars:nativeAppInstallAd.starRating];
// In order for the SDK to process touch events properly, user interaction
// should be disabled on UIButtons.
appInstallAdView.callToActionView.userInteractionEnabled = NO;
// Add appInstallAdView to the view controller's view..
[self.myNativeAdPlaceholder addSubview:appInstallAdView];
}
As you can see, the code example above disables user interaction for the UIButton that displays the call to action. If you use UIButtons to display native ad assets, you'll 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.
Loading custom native ad formats
Like their system-defined counterparts,
custom native ad formats are loaded using GADAdLoader
objects.
Including the kGADAdLoaderAdTypeNativeCustomTemplate
constant
in the adTypes
array when initializing a GADAdLoader
will configure it to request custom native formats when loading ads.
GADNativeCustomTemplateAdLoaderDelegate
The protocol for loading custom templates has two methods.
The first is used by GADAdLoader
to find out which template IDs it should request:
- (NSArray *)nativeCustomTemplateIDsForAdLoader:(GADAdLoader *)adLoader;
Every custom native ad format has a corresponding template ID that identifies it. When this method is called, your app should return an array containing the template IDs of the formats it's prepared to display.
The second message is sent when the custom template ad has loaded, much like those for system-defined formats:
- (void)didReceiveNativeCustomTemplateAd:(GADNativeCustomTemplateAd *)nativeCustomTemplateAd;
Template IDs
The template IDs used to uniquely refer to native custom ad formats can be found in the DFP UI under the Creatives > Native Ad Formats section of the Orders tab:
Each custom native ad format's template ID appears beneath its name. Clicking on one of the names brings you to a details screen showing information about the template's fields:
From here, individual fields can be added, edited, and removed. Note the Variable ID column to the right. These IDs are used to access the individual assets, and will be discussed more in the next section.
Displaying custom native ad formats
Custom native ad formats differ from system-defined formats in that publishers have the power to define their own "templates," or lists of assets, that make up an ad. Because of this, the process for displaying custom native ads differs from the one for system-defined formats in a few ways:
- Because
GADNativeCustomTemplateAd
is meant to handle any of the custom native ad formats you create, it doesn't have named asset accessors. Instead, it offers methods likeimageForKey:
andstringForKey:
that take the Variable ID of a template field as an argument. - There is no dedicated ad view class like
GADNativeContentAdView
to use withGADNativeCustomTemplateAd
. You are free to use whatever interface makes sense for your user experience. - Because there is no dedicated ad view class, you do not need to register any of the views you use to display the ad's assets.
Here is an example of a class capable of displaying a simple
GADNativeCustomTemplateAd
:
MySimpleNativeAdView.h
@import UIKit;
@import GoogleMobileAds;
/// View representing a custom native ad format with template ID 10063170.
@interface MySimpleNativeAdView : UIView
// Weak references to this ad's asset views.
@property(weak, nonatomic) IBOutlet UILabel *headlineView;
@property(weak, nonatomic) IBOutlet UIImageView *mainImageView;
@property(weak, nonatomic) IBOutlet UILabel *captionView;
/// Populates the ad view with the custom native ad object.
- (void)populateWithCustomNativeAd:(GADNativeCustomTemplateAd *)customNativeAd;
@end
MySimpleNativeAdView.m (excerpt)
...
- (void)populateWithCustomNativeAd:(GADNativeCustomTemplateAd *)customNativeAd {
self.customNativeAd = customNativeAd;
// Populate the custom native ad assets.
self.headlineView.text = [customNativeAd stringForKey:@"Headline"];
self.mainImageView.image = [customNativeAd imageForKey:@"MainImage"].image;
self.captionView.text = [customNativeAd stringForKey:@"Caption"];
}
...
Handling custom native ad format clicks and impressions
For custom native ad formats, your app is responsible for recording impressions and for reporting click events to the SDK.
Recording impressions
To record an impression for a custom template ad,
just call the recordImpression
method
on the corresponding GADNativeCustomTemplateAd
:
[myCustomTemplateAd recordImpression];
The SDK prevents duplicate impressions from being recorded for a single request, should your app accidentally call the method multiple times for the same ad.
Reporting clicks
To report to the SDK that a click has occurred on an asset view,
call the performClickOnAssetWithKey:customClickHandler:
method
on the corresponding GADNativeCustomTemplateAd
and pass in the name of the asset that was clicked
along with an optional custom click handler (more on these below).
For example,
if you had an asset in your custom template called "MainImage"
and wanted to report a click on the view that corresponded to that asset,
your code would look like this:
[myCustomTemplateAd performClickOnAssetWithKey:@"MainImage"
customClickHandler:^{ /* an optional block */ }];
Note that you don't need to call this method
for every asset view associated with your ad.
If you had another asset called "Caption,"
for instance,
that was meant to be displayed
but not clicked or tapped on by the user,
your app would not need to call
performClickOnAssetWithKey:customClickHandler:
for that view.
Responding to custom click actions
When a click is performed on a custom template ad, there are three possible responses from the SDK, attempted in this order:
- Invoke the
customClickHandler
block, if one was passed in. - Loop through the ad's Deeplink URLs and open the first one for which a matching app can be found.
- Open a browser and navigate to the ad's traditional Destination URL.
The performClickOnAssetWithKey:customClickHandler:
method
accepts a block as its second parameter.
If you pass in a block,
the SDK will run it and take no further action.
If you pass in a nil value,
however,
the SDK will fall back to the deeplink and/or destination URLs
registered with the ad.
Custom click handlers allow your app to decide for itself the best action to take in response to a click, whether it's updating the UI, presenting another view controller, or merely logging the click. Here's an example that shows an alert:
[self.customTemplateAd
performClickOnAssetWithKey:@"MainImage"
customClickHandler:^{
[[[UIAlertView alloc] initWithTitle:@"Custom Click"
message:@"You just clicked on the image!"
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil] show];
}];
Testing native ad code
Direct-sold ads
If you'd like to test out what direct-sold native ads are like, you can make use of this DFP ad unit ID:
/6499/example/native
It's configured to serve sample app install and content ads, as well as a custom native ad format with the following assets:
- Headline (text)
- MainImage (image)
- Caption (text)
The template ID for the custom native ad format is 10063170.
Please note that at the current time,
publishers should not use the testDevices
property
with native ad requests.
Using the above ad unit ID with no devices
registered via the testDevices
property
is the current best practice for testing.
Native backfill ads
To test the behavior of native backfill ads, use this DFP ad unit:
/6499/example/native-backfill
It will serve sample app install and content ads that include the AdChoices overlay.
Remember to update your code to refer to your actual ad unit and template IDs before going live!