What is Native Ads Manager?

Creating a seamless user experience is important for apps. We've built the Native Ads Manager to help with requesting, storing, and delivering the most relevant ad at the right time.

When should I use Native Ads Manager?

Use the Native Ads Manager when your user experience involves displaying multiple ads within a short amount of time, such as a vertical feed or horizontal scroll. An app can also use Native Ads Manager to automatically refresh and deliver ads.

How do I integrate?

Implement the Native Ads Manager along side your Native Ads integration. Native Ads Manager can be used with a publisher defined View (leveraging the Native Ads API) or with the Native Ads Template.

Native Ads Manager with Table View Controller

Let's implement a table view controller that uses the native ad manager to present a list of ads as follows:



Step 1: Create Table View Controller

Step 2: Use NativeAdManager to Request Ads

Step 3: Use NativeAdManager to Show Ads

Step 1: Create Table View Controller

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

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



  2. Open ViewController.m, add UITableViewDataSource and UITableViewDelegate. Next add tableView, adsManager, ads, and tableViewContentArray instance variables.
    @interface ViewController () <UITableViewDataSource, UITableViewDelegate>
    
    @property (weak, nonatomic) IBOutlet UITableView *tableView;
    @property (strong, nonatomic) FBNativeAdsManager *adsManager;
    @property (strong, nonatomic) FBNativeAdTableViewCellProvider *ads;
    @property (strong, nonatomic) NSMutableArray *tableViewContentArray;
    
    @end
    		
    adsManager is used for requesting and storing the list of NativeAd instances.
    ads is used for providing the UITableViewCell that shows the content of ad.
    tableViewContentArray is used for storing the normal non-ad content.

  3. Add the implementation for tableViewContentArray property to store the normal non-ad content as follows:
    - (NSMutableArray *)tableViewContentArray {
        if (!_tableViewContentArray) {
            _tableViewContentArray = [NSMutableArray array];
            for (NSUInteger i = 0; i < 10; i++) {
                NSString *displayText = [NSString stringWithFormat:@"TableView Cell #%lu", (unsigned long)(i + 1)];
                [_tableViewContentArray addObject:displayText];
            }
        }
        
        return _tableViewContentArray;
    }		
    tableViewContentArray is an array that contains a list of string text indexed from 1 to 10. And it will be displayed in a regular cell.

  4. In viewDidLoad method, add the following lines of code to setup for the table view property.
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"kDefaultCellIdentifier"];
    
    You will need to implement the required methods for UITableViewDataSource and UITableViewDelegate to show contents in the table view.
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
       return [self.tableViewContentArray count];
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kDefaultCellIdentifier forIndexPath:indexPath];
        indexPath = [self.ads adjustNonAdCellIndexPath:indexPath forStride:kRowStrideForAdCell] ?: indexPath;
        cell.textLabel.text = [self.tableViewContentArray objectAtIndex:indexPath.row];
        return cell;
    }
    		
  5. Build and run in device or simulator. You should be able to see list of table view cells with string text indexed from 1 to 10 as follows:

Step 2: Use NativeAdManager to Request Ads

You now have created a table view sample app that shows regular cells. Next, you will use NativeAdManager to request ads.

  1. In this sample app, it will show one ad cell for every 3 regular cells. First define a static variable used for calculating which cell contains ad content as follows:
    static NSInteger const kRowStrideForAdCell = 3; 
    
  2. Add FBNativeAdsManagerDelegate and FBNativeAdDelegate delegates to the ViewController class.
    @interface ViewController () <UITableViewDataSource, UITableViewDelegate, FBNativeAdsManagerDelegate, FBNativeAdDelegate>
    @end
    FBNativeAdsManagerDelegate is used for notifying whether ads are finished loading by FBNativeAdsManager or an error is returned.
    FBNativeAdDelegate is used for notifying an ad being viewed or clicked by a user.

  3. In viewDidLoad method, add the following lines of code:
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.tableView.delegate = self;
        self.tableView.dataSource = self;
        [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kDefaultCellIdentifier];
        
        if (!self.adsManager) {
            self.adsManager = [[FBNativeAdsManager alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"
                                                           forNumAdsRequested:5];
            // Set a delegate to get notified when the ads are loaded.
            self.adsManager.delegate = self;
            
            // Configure native ad manager to wait to call nativeAdsLoaded until all ad assets are loaded
            self.adsManager.mediaCachePolicy = FBNativeAdsCachePolicyAll;
        }
        
        // Load some ads
        [self.adsManager loadAds];
    }
    
    When initializing and creating adManager, 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.

    In this example, let's request maximum 5 number of ads. This can be set in [FBNativeAdsManager initWithPlacementID: forNumAdsRequested:]

    Set mediaCachePolicy to be FBNativeAdsCachePolicyAll. This will configure the native ad to wait to be called in nativeAdDidLoad method until all ad assets are loaded.

    Audience Network supports five cache options in native ads as defined in the FBNativeAd.h:
    Cache Constants Description

    NONE

    No pre-caching, default

    ICON

    Pre-cache ad icon

    IMAGE

    Pre-cache ad images

    VIDEO

    Pre-cache ad video

    ALL

    Pre-cache all (icon, images, and video)

    You need to call [self.adsManager loadAds]; to load ad.

  4. You need to implement nativeAdsLoaded and nativeAdsFailedToLoadWithError to check if ads are loaded successfully by the adsManager as follows:
    #pragma mark FBNativeAdsManagerDelegate implementation
    
    - (void)nativeAdsLoaded {
        NSLog(@"Native ad was loaded, constructing native UI...");
    }
    
    - (void)nativeAdsFailedToLoadWithError:(NSError *)error {
        NSLog(@"Native ad failed to load with error: %@", error);
    }
    
    Build and run the app. You should see the log message "Native ad was loaded" if ads are loaded successfully.

Step 3: Use NativeAdManager to Show Ads

In this step, you will learn how to use FBNativeAdTableViewCellProvider to display ads in the table view cell.

  1. In nativeAdsLoaded method, add the following lines of code.
    - (void)nativeAdsLoaded {
        NSLog(@"Native ad was loaded, constructing native UI...");
        FBNativeAdTableViewCellProvider *cellProvider =
            [[FBNativeAdTableViewCellProvider alloc] initWithManager:self.adsManager
                                                             forType:FBNativeAdViewTypeGenericHeight300];
        self.ads = cellProvider;
        self.ads.delegate = self;
        
        [self.tableView reloadData];
    }
    
    The native ad cell provider operates over a loaded ads manager and can create table cells with native ad templates in them as well as help with the math to have a consistent distribution of ads within a table.

  2. You will modify numberOfRowsInSection, cellForRowAtIndexPath and heightForRowAtIndexPath methods as follows:
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        // In this example the ads are evenly distributed within the table every kRowStrideForAdCell-th cell.
        NSUInteger count = [self.tableViewContentArray count];
        count = [self.ads adjustCount:count forStride:kRowStrideForAdCell] ?: count;
        return count;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        // For ad cells just as the ad cell provider, for normal cells do whatever you would do.
        if ([self.ads isAdCellAtIndexPath:indexPath forStride:kRowStrideForAdCell]) {
            return [self.ads tableView:tableView cellForRowAtIndexPath:indexPath];
        } else {
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kDefaultCellIdentifier forIndexPath:indexPath];
            // In this example we need to adjust the index back to the domain of the data.
            indexPath = [self.ads adjustNonAdCellIndexPath:indexPath forStride:kRowStrideForAdCell] ?: indexPath;
            cell.textLabel.text = [self.tableViewContentArray objectAtIndex:indexPath.row];
            return cell;
        }
    }
    
    #pragma mark - UITableViewDelegate
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        // The ad cell provider knows the height of ad cells based on its configuration
        if ([self.ads isAdCellAtIndexPath:indexPath forStride:kRowStrideForAdCell]) {
            return [self.ads tableView:tableView heightForRowAtIndexPath:indexPath];
        } else {
            return 80;
        }
    }
    
    In numberOfRowsInSection method, [FBNativeAdTableViewCellProvider adjustCount:forStride] is called to calculate the number of cells including normal content and ads.

    In cellForRowAtIndexPath method, [FBNativeAdTableViewCellProvider isAdCellAtIndexPath:forStride] is called first to determine if the current cell contains the ad content.

    [FBNativeAdTableViewCellProvider tableView:cellForRowAtIndexPath:] fetches the cell instance that contains ad content.

    If the cell that will be shown contains regular content, you need to call [FBNativeAdTableViewCellProvider adjustNonAdCellIndexPath:forStride:] to adjust the index back to the domain of the data.

    In heightForRowAtIndexPathmethod, you need to use [FBNativeAdTableViewCellProvider tableView:heightForRowAtIndexPath:] to fetch the height of a cell that contains the ad content.

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

When running in the simulator, you need to set test mode to view test ads. Please refer to How to Use Test Mode for more information.

Next Steps

  • Submit your app for review.

  • As soon as we receive a request for an ad from your app or website, we'll review it to make sure it complies with Audience Network policies and the Facebook community standards. Learn more about our review process.

  • Explore our code samples which demonstrate how to use native ads. The NativeAdSample is available as part of the SDK and can be found under the FBAudienceNetwork/samples folder. Open the project with Xcode and run it either on a device or the simulator.

When using latest Xcode with Facebook Audience Network samples, Xcode will give signing error that the app id used in the sample app cannot be registered to your development team. You would need to change your bundle identifier to a unique string and try again.