Audience Network

Adding Native Ads to your iOS App

Updated: Jun 30, 2026
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

Native ad layout with 8 numbered views: advertiser icon, title, sponsored label, ad choices, media, social context, body, and Learn More button

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.
    Xcode storyboard editor with a UIView named adUIView added to the main view controller scene

  2. In addition, add adIconImageView (FBMediaView), adTitleLabel (UILabel), adCoverMediaView (FBMediaView), adSocialContext (UILabel), adCallToActionButton (UIButton), adOptionsView (FBAdOptionsView), adBodyLabel (UILabel), sponsoredLabel (UILabel) under adUIView as illustrated in the image below.
    Xcode storyboard showing all native ad subviews (icon, title, media, social context, CTA button, options, body, sponsored) nested under adUIView

  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.
    Xcode outline with a red error indicator next to View Controller Scene, signaling missing layout constraints

    You would need to select all the view objects in your scene and click the "resolve layout issue" icon to add missing constraints.
    Xcode resolve layout issues menu with Add Missing Constraints highlighted to fix constraint errors

  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 (ViewController.swift if you are using Swift), then drag adUIView inside the ViewController object. You can name it as adUIView. After, you will need to do the same thing for adIconImageView , adTitleLabel, adCoverMediaView, adSocialContext, adCallToActionButton, adOptionsView, adBodyLabel, sponsoredLabel.
    Xcode storyboard beside the ViewController source file showing IBOutlet properties connected to the native ad views

  5. Build and run the project. You should see from your device or simulator empty content as follows:
    iPhone simulator showing the empty native ad layout with Title, Sponsor, Social Context, Body labels and a blank call-to-action area
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. In your View Controller source file, import the SDK, declare that ViewController conforms to the FBNativeAdDelegate protocol, and add a FBNativeAd instance variable
    import UIKit
    import FBAudienceNetwork
    
    class ViewController: UIViewController, FBNativeAdDelegate {
    
      private var nativeAd: FBNativeAd?
    }
    

  2. In the viewDidLoad method, add the following lines of code to load the native ad content
    override func viewDidLoad() {
      super.viewDidLoad()
    
      let nativeAd = FBNativeAd(placementID: "YOUR_PLACEMENT_ID")
      nativeAd.delegate = self
      nativeAd.loadAd()
    }
    

    The ID that displays at YOUR_PLACEMENT_ID is a temporary ID for test purposes only.
    If you use this temporary ID in your live code, your users will not receive ads (they will get a No Fill error). You must return here after testing and replace this temporary ID with a live Placement ID.
    To find out how the generate a live Placement ID, refer to Audience Network Setup
  3. The next step is to show the ad when the content is ready. You would need your ViewController to implement the nativeAdDidLoad delegate method
    func nativeAdDidLoad(_ nativeAd: FBNativeAd) {
    
    // 1. If there is an existing valid native ad, unregister the view
    if let previousNativeAd = self.nativeAd, previousNativeAd.isAdValid {
      previousNativeAd.unregisterView()
    }
    
    // 2. Retain a reference to the native ad object
    self.nativeAd = nativeAd
    
    // 3. Register what views will be tappable and what the delegate is to notify when a registered view is tapped
    // Here only the call-to-action button and the media view are tappable, and the delegate is the view controller
    nativeAd.registerView(
      forInteraction: adUIView,
      mediaView: adCoverMediaView,
      iconView: adIconImageView,
      viewController: self,
      clickableViews: [adCallToActionButton, adCoverMediaView]
    )
    
      // 4. Render the ad content onto the view
      adTitleLabel.text = nativeAd.advertiserName
      adBodyLabel.text = nativeAd.bodyText
      adSocialContextLabel.text = nativeAd.socialContext
      sponsoredLabel.text = nativeAd.sponsoredTranslation
      adCallToActionButton.setTitle(nativeAd.callToAction, for: .normal)
      adOptionsView.nativeAd = nativeAd
    }
    
  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.


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

    iPhone simulator showing a rendered Jasper's Market native ad with icon, sponsored label, cookware images, body text, and an Open Link button

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. Declare that your View Controller implements the FBMediaViewDelegate protocol
    class ViewController: UIViewController, FBNativeAdDelegate, FBMediaViewDelegate {
      ...
    }
    

  2. When the native ad is loaded, set the delegate of FBMediaView object to be your view controller
    func nativeAdDidLoad(_ nativeAd: FBNativeAd) {
      adCoverMediaView.delegate = self
    }
    

  3. Implement mediaViewDidLoad method in your view controller
    func mediaViewDidLoad(_ mediaView: FBMediaView) {
      let currentAspect = mediaView.frame.size.width / mediaView.frame.size.height
      print(currentAspect)
    
      let actualAspect = mediaView.aspectRatio
      print(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
func nativeAdDidClick(_ nativeAd: FBNativeAd) {
  print("Native ad was clicked.")
}

func nativeAdDidFinishHandlingClick(_ nativeAd: FBNativeAd) {
  print("Native ad did finish click handling.")
}

func nativeAdWillLogImpression(_ nativeAd: FBNativeAd) {
  print("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 to handle ad loading failures
func nativeAd(_ nativeAd: FBNativeAd, didFailWithError error: Error) {
  print("Native ad failed to load with error: \(error.localizedDescription)")
}

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
    let nativeAd = FBNativeAd(placementID: "YOUR_PLACEMENT_ID")
    nativeAd.delegate = self
    nativeAd.loadAd(withMediaCachePolicy: .none)
    

  2. First, you will need to manually download all media for the native ad
    func nativeAdDidLoad(_ nativeAd: FBNativeAd) {
    
    ...
    
    self.adCoverMediaView.delegate = self
    nativeAd.downloadMedia()
    self.nativeAd = nativeAd
    
      ...
    }
    

  3. Next, you should only call registerViewForInteraction and display the ad after mediaViewDidLoad callback. All media has to be loaded and displayed for an eligible impression
    func mediaViewDidLoad(_ mediaView: FBMediaView) {
      guard let nativeAd = nativeAd else {
        return
      }
    
    // 1. Register what views will be tappable and what the delegate is to notify when a registered view is tapped
    // Here only the call-to-action button and the media view are tappable, and the delegate is the view controller
    nativeAd.registerView(
      forInteraction: adUIView,
      mediaView: mediaView,
      iconView: adIconImageView,
      viewController: self,
      clickableViews: [adCallToActionButton, mediaView]
    )
    
      // 2. Render the ad content onto the view
      adTitleLabel.text = nativeAd.advertiserName
      adBodyLabel.text = nativeAd.bodyText
      adSocialContextLabel.text = nativeAd.socialContext
      sponsoredLabel.text = nativeAd.sponsoredTranslation
      adCallToActionButton.setTitle(nativeAd.callToAction, for: .normal)
      adOptionsView.nativeAd = nativeAd
    }
    

Next steps

  • Once your app has a link on the App Store or Google Play Store, configure Audience Network in Monetization Manager to get ad placement IDs.
  • Follow the guides to implement ad formats in your app.

See also

More Resources

Technical guide to get started with the Audience Network
Audience Network Ads Integration Samples
Audience Network FAQ
A more hands off approach when integrating Native Ads