Adding the Native Ad API in iOS

The Native Ad API allows you to build a customized experience for the ads you show in your app. When using the Native Ad API, instead of receiving an ad ready to be displayed, you will receive a group of ad properties such as a title, an image, a call to action, and you will have to use them to construct a custom UIView where the ad is shown.

Please consult our native ads guide when designing native ads in your app.

Let's implement the following native ad placement. You will create the following views to our native ad.

View #1: advertiser icon

View #2: ad title

View #3: sponsored label

View #4: advertiser choice

View #5: ad media view

View #6: social context

View #7: ad body

View #8: ad call to action button


Step 1: Create Native Ad Views in Storyboard

Step 2: Load and Show Native Ad

Step 3: How to Get Aspect Ratio of the Content and Apply Natural Width and Height

Step 4: Verify Impression and Click Logging

Step 5: How to Debug When Ad Not Shown

Step 6: Load Ad without Auto Cache

Step 7: Test Ads Integration

See Known Issues in the Change Log

Step 1: Create Native Ad Views in Storyboard

Ensure you have completed the Audience Network Getting Started and iOS Getting Started guides before you proceed.

When designing native ads and banner ads, ensure you have followed iOS layout guideline for optimal user experience.

  1. After you have created a new project from iOS Getting Started guides, open Main.storyboard. Add a UIView element to the main View element and name it to AdUIView.

  2. In addition, add adIconImageView (FBAdIconView), adTitleLable (UILabel), adCoverMediaView (FBMediaView), adSocialContext (UILabel), adCallToActionButton (UIButton), adChoiceView (FBAdChoicesView), adBodyLabel (UILabel), sponsoredLabel (UILabel) under AdUIView as illustrated in the image below.

  3. You may notice that there is a red arrow nearby View Controller Scene. This usually means that there are missing constraints in your layout.


    You would need to select all the view objects in your scene and click the "resolve layout issue" icon to add missing constraints.



  4. Now that you have created all the UI elements for showing a native ad, you will need to reference these UI elements in the ViewController interface. First open the ViewController.m, then drag adUIView inside the ViewController interface object. You can name it as adUIView. After, you will need to do the same thing for adIconImageView , adTitleLable, adCoverMediaView, adSocialContext, adCallToActionButton, adChoiceView, adBodyLabel, sponsoredLabel.

  5. Build and run the project. You should see from your device or simulator empty content as follows:

Now that you have created all the UI elements to show native ads, the next step is to load the native ad and bind the contents to the UI elements.

Step 2: Load and Show Native Ad

  1. Now, in your View Controller header file, import the SDK header, declare that ViewController implements the FBNativeAdDelegate protocol and add a nativeAd instance variable:
    #import <UIKit/UIKit.h>
    @import FBAudienceNetwork;
    
    @interface ViewController () <FBNativeAdDelegate>
    
    @property (strong, nonatomic) FBNativeAd *nativeAd;
    
    @end
  2. In viewDidLoad method, add the following lines of code to load native ad content.
    - (void)viewDidLoad 
    {
        [super viewDidLoad];
        FBNativeAd *nativeAd = [[FBNativeAd alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"];
        nativeAd.delegate = self;
        [nativeAd loadAd];
    }
    Replace YOUR_PLACEMENT_ID with your own placement id string. If you don't have a placement id or don't know how to get one, you can refer to the Getting Started Guide

  3. The next step is to show ad when content is ready. You would need to implement nativeAdDidLoad method in ViewController.m file.
    - (void)nativeAdDidLoad:(FBNativeAd *)nativeAd
    {
        self.nativeAd = nativeAd;
        [self showNativeAd];
    }
    
    - (void)showNativeAd
    {
        if (self.nativeAd && self.nativeAd.isAdValid) {
            [self.nativeAd unregisterView];
    
            // Wire up UIView with the native ad; only call to action button and media view will be clickable.
            [nativeAd registerViewForInteraction:self.adUIView
                              viewController:self
                                   mediaView:self.adCoverMediaView
                                    iconView:self.adIconImageView               
                          withClickableViews:@[self.adCallToActionButton, self.adCoverMediaView]];
    
            // Render native ads onto UIView
            self.adTitleLabel.text = self.nativeAd.title;
            self.adBodyLabel.text = self.nativeAd.body;
            self.adSocialContextLabel.text = self.nativeAd.socialContext;
            self.sponsoredLabel.text = @"Sponsored";
            [self.adCallToActionButton setTitle:self.nativeAd.callToAction
                                       forState:UIControlStateNormal];
            self.adChoicesView.nativeAd = nativeAd;
            self.adChoicesView.corner = UIRectCornerTopRight;
        }
    }
    First, you will need to check if there is an existing nativeAd object. If there is, you will need to call unregisterView method. Then you will call [nativeAd registerViewForInteraction:viewController:mediaView:iconView:clickableViews:] method.

    What registerViewForInteraction mainly does is register what views will be tappable and what the delegate is to notify when a registered view is tapped. In this case, adCallToActionButton and adCoverMediaView will be tappable and when the view is tapped, ViewController will be notified through FBNativeAdDelegate.

  4. Controlling Clickable Area

    For a better user experience and better results, you should always consider controlling the clickable area of your ad to avoid unintentional clicks. Please refer to Audience Network SDK Policy page for more details about white space unclickable enforcement.

    For finer control of what is clickable, you can use the [nativeAd registerViewForInteraction:viewController:mediaView:iconView:clickableViews:] method to register a list of views that can be clicked.

  5. Choose your build target to be device and run the above code, you should see something like this:



When running ads in the simulator, change the setting to test mode to view test ads. Please go to How to Use Test Mode for more information.

Step 3: How to Get the Aspect Ratio of the Content and Apply Natural Width and Height

In the example above, the media content of the ad is shown in adCoverMediaView and its object type is FBMediaView. From previous step, we have shown how to use FBMediaView to load media content from a given FBNativeAd object. This view takes the place of manually loading a cover image. When creating the FBMediaView, its width and height can be either determined by the auto layout constraints set in the storyboard, or they can be hard-coded. However, the width and height of the view may not be fit with the actual cover image of the ad downloaded later. To fix this, the example following shows how to get the aspect ratio of the content and apply natural width and height:

  1. In your View Controller header file, declare that ViewController implements the FBMediaViewDelegate protocol as follows:
    @interface ViewController : UIViewController <FBNativeAdDelegate, FBMediaViewDelegate>
  2. When the native ad is loaded, set the delegate of FBMediaView object to be the controller self as follows:
    - (void)nativeAdDidLoad:(FBNativeAd *)nativeAd 
    {
      self.adCoverMediaView.delegate = self;
    }
  3. Implement mediaViewDidLoad method in ViewController as follows:
    - (void)mediaViewDidLoad:(FBMediaView *)mediaView
    {
      CGFloat currentAspect = mediaView.frame.size.width / mediaView.frame.size.height;
      NSLog(@"current aspect of media view: %f", currentAspect);
      
      CGFloat actualAspect = mediaView.aspectRatio;
      NSLog(@"actual aspect of media view: %f", actualAspect);
    }
    mediaView.aspectRatio returns a positive CGFloat, or 0.0 if no ad is currently loaded. Its value is valid after media view is loaded. There are convenience methods that will set the width and height of the FBMediaView object respecting its apsect ratio of the media content loaded. You can call applyNaturalWidth or applyNaturalHeight to update the FBMediaView object's width or height to respect the media content's aspect ratio.

Step 4: Verify Impression and Click Logging

Optionally, you can add the following functions to handle the cases where the native ad is closed or when the user clicks on it:

- (void)nativeAdDidClick:(FBNativeAd *)nativeAd
{
    NSLog(@"Native ad was clicked.");
}

- (void)nativeAdDidFinishHandlingClick:(FBNativeAd *)nativeAd
{
    NSLog(@"Native ad did finish click handling.");
}

- (void)nativeAdWillLogImpression:(FBNativeAd *)nativeAd
{
    NSLog(@"Native ad impression is being captured.");
}

Step 5: How to Debug When Ad Not Shown

Add and implement the following function in your View Controller implementation file to handle ad loading failures and completions:

- (void)nativeAd:(FBNativeAd *)nativeAd didFailWithError:(NSError *)error
{
    NSLog(@"Native ad failed to load with error: %@", error);
}

Step 6: Load Ad without Auto Cache

  1. We strongly recommend to leave media caching on by default in all cases. However, we allow you to override the default. Please be very careful if you decide to override our default media caching.
    @interface ViewController () <FBNativeAdDelegate, FBMediaViewDelegate>
    
    ...
    
    - (void)viewDidLoad 
    {
        [super viewDidLoad];
        FBNativeAd *nativeAd = [[FBNativeAd alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"];
        nativeAd.delegate = self;
        [nativeAd loadAdWithMediaCachePolicy:FBNativeAdsCachePolicyNone];
    }
  2. First, you will need to manually download all media for the native ad.
    - (void)nativeAdDidLoad:(FBNativeAd *)nativeAd
    {
        self.adCoverMediaView.delegate = self;
        [nativeAd downloadMedia];
        self.nativeAd = nativeAd;
    }
  3. Next, you should only call registerViewForInteraction and display ad after mediaViewDidLoad callback. All media has to be loaded and displayed for an eligible impression.
    - (void)mediaViewDidLoad:(FBMediaView *)mediaView 
    {
        [self showNativeAd];
    }
    
    - (void)showNativeAd
    {
        if (self.nativeAd && self.nativeAd.isAdValid) {
            [self.nativeAd unregisterView];
    
            self.adCoverMediaView = mediaView;        
            // Wire up UIView with the native ad; only call to action button and media view will be clickable.
            [nativeAd registerViewForInteraction:self.adUIView
                              viewController:self
                                   mediaView:self.adCoverMediaView
                                    iconView:self.adIconImageView               
                          withClickableViews:@[self.adCallToActionButton, self.adCoverMediaView]];
    
            // Render native ads onto UIView
            self.adTitleLabel.text = self.nativeAd.title;
            self.adBodyLabel.text = self.nativeAd.body;
            self.adSocialContextLabel.text = self.nativeAd.socialContext;
            self.sponsoredLabel.text = @"Sponsored";
            [self.adCallToActionButton setTitle:self.nativeAd.callToAction
                                       forState:UIControlStateNormal];
            self.adChoicesView.nativeAd = nativeAd;
            self.adChoicesView.corner = UIRectCornerTopRight;
        }
    }

Next Steps

More Resources

Getting Started Guide

Technical guide to get started with the Audience Network

Code Samples

Audience Network Ads Integration Samples

Native Ads Template

A more hands off approach when integrating Native Ads

API Reference

Facebook SDK for iOS Reference

FAQ

Audience Network FAQ

Horizontal Scroll

Implement a horizontal scroll unit to maximize ad space