Get Started

Integrating Native Ads Using Ad Placer – iOS


Native ads let you easily monetize your app in a way that’s consistent with its existing design. The MoPub SDK gives you access to an ad’s individual assets so you can lay them out the way you want to; that way, the ad looks and feels like the rest of your app. The SDK automatically handles asset caching and metric tracking so you can focus on how, when, and where to display ads.

Prerequisites

  • Before integrating native ads in your app, you’ll need to create an account on MoPub
  • Integrate the SDK into your project.
  • Read the best practices article for guidelines on how native ads can be displayed in your app.

Privacy Information Icon

Your native ad cells must display the privacy information icon (“daaIconImageView). Integrating a privacy information icon into your cells is outlined in the Place Ads in a UITableView and Place Ads in a UICollectionView sections. The MoPub SDK automatically handles tap events on the privacy information icon.

`MPNativeAdRendering` Protocol

Your native ad `UITableViewCell` and `UICollectionViewCell` subclasses must adopt the `MPNativeAdRendering` protocol.

`MPNativeAdRendering` class documentation available here.

Optional method `+ (CGSize)sizeWithMaximumWidth:(CGFloat)maximumWidth` must be implemented to return the correct size for your native ad cell.

Optional method `+ (UINib *)nibForAd` must be implemented if you use a nib for your native ad cell.


Place Ads in a UITableView

The MoPub SDK provides a helper class, `MPTableViewAdPlacer`, that handles requesting ads from MoPub and inserting them into your existing `UITableView` subclass.

When an instance of `MPTableViewAdPlacer` is initialized with a table view, it wraps the table view’s data source and delegate in order to insert ads and adjust the positions of your regular content cells.

In your `UITableView` feed `UIViewController`’s `viewDidLoad`

1. Create an `MPServerAdPositioning` object.  This object informs the MPTableViewAdPlacer about where to place ads within the table view.

MPServerAdPositioning *positioning = [[MPServerAdPositioning alloc] init];

2. Set up your preferred ad positioning in the MoPub UI in the ad unit settings page. The `MPServerAdPositioning` object receives ad positions from those settings.

3. Instantiate your `MPTableViewAdPlacer` with your `UITableView` instance and your `MPServerAdPositioning` object.

self.placer = [MPTableViewAdPlacer placerWithTableView:self.tableView viewController:self adPositioning:positioning defaultAdRenderingClass:[YourNativeAdCell class]];

`self.tableView` is the `UITableView` that contains your feed.
`YourNativeAdCell` is a `UITableViewCell` subclass that implements the `MPNativeAdRendering` protocol.

    // YourNativeAdCell.h
    
    @interface YourNativeAdCell : UITableViewCell 
    
    @property (strong, nonatomic) UILabel *titleLabel;
    @property (strong, nonatomic) UILabel *mainTextLabel;
    @property (strong, nonatomic) UIButton *callToActionButton;
    @property (strong, nonatomic) UIImageView *iconImageView;
    @property (strong, nonatomic) UIImageView *mainImageView;
    @property (strong, nonatomic) UIImageView *daaIconImageView;
    
    @end
    
    // YourNativeAdCell.m
    
    @implementation YourNativeAdCell
    
    ...
    
    - (void)layoutAdAssets:(MPNativeAd *)adObject
    {
        [adObject loadTitleIntoLabel:self.titleLabel];
        [adObject loadTextIntoLabel:self.mainTextLabel];
        [adObject loadCallToActionTextIntoLabel:self.callToActionButton.titleLabel];
        [adObject loadIconIntoImageView:self.iconImageView];
        [adObject loadImageIntoImageView:self.mainImageView];
        [adObject loadImageIntoImageView:self.daaIconImageView];
    }
    
    + (CGSize)sizeWithMaximumWidth:(CGFloat)maximumWidth
    {
        return CGSizeMake(maximumWidth, kNativeAdCellHeight);
    }

    // You MUST implement this method if YourNativeAdCell uses a nib
    + (UINib *)nibForAd
    {
        return [UINib nibWithNibName:@"YourNativeAdCell" bundle:nil];
    }

    @end

4. Add targeting parameters to provide more information about your ad to the advertiser, and conserve bandwidth by getting only the right assets.

MPNativeAdRequestTargeting *targeting = [MPNativeAdRequestTargeting targeting]; targeting.desiredAssets = [NSSet setWithObjects:kAdIconImageKey, kAdMainImageKey, kAdCTATextKey, kAdTextKey, kAdTitleKey, nil];

See more details on passing information like location in our Data Passing doc.

5. Instruct your `MPTableViewAdPlacer` instance to begin loading ads and placing them into your feed, using the ad unit ID you created in the MoPub dashboard.

[self.placer loadAdsForAdUnitID:@"YOUR_ADUNIT_ID"];

6. Replace `UITableView` Method Calls

Replace calls to the following `UITableView` methods with the MoPub SDK category equivalents.

Instead of:

[self.tableView selectRowAtIndexPath:myIndexPath]; 

Use:

[self.tableView mp_selectRowAtIndexPath:myIndexPath];

These methods work just like the regular `UITableView` methods, except that they make adjustments to the `NSIndexPath` parameters to handle the fact that your stream has extra ad rows.

IMPORTANT: These replacements are mandatory. If you skip this step, you will see problems related to your content row positions being out of sync with your table view.

ORIGINAL REPLACEMENT
setDelegate: mp_setDelegate:
delegate mp_delegate
setDataSource: mp_setDataSource:
dataSource mp_dataSource
reloadData mp_reloadData
rectForRowAtIndexPath: mp_rectForRowAtIndexPath:
indexPathForRowAtPoint: mp_indexPathForRowAtPoint:
indexPathForCell: mp_indexPathForCell:
indexPathsForRowsInRect: mp_indexPathsForRowsInRect:
cellForRowAtIndexPath: mp_cellForRowAtIndexPath:
visibleCells mp_visibleCells
indexPathsForVisibleRows: mp_indexPathsForVisibleRows:
scrollToRowAtIndexPath:atScrollPosition:animated: mp_scrollToRowAtIndexPath:atScrollPositions:animated:
beginUpdates mp_beginUpdates
endUpdates mp_endUpdates
insertSections:withRowAnimation: mp_insertSections:withRowAnimation:
deleteSections:withRowAnimation: mp_deleteSections:withRowAnimation:
reloadSections:withRowAnimation: mp_reloadSections:withRowAnimation:
moveSection:toSection: mp_moveSection:toSection:
insertRowsAtIndexPaths:withRowAnimation: mp_insertRowsAtIndexPaths:withRowAnimation:
deleteRowsAtIndexPaths:withRowAnimation: mp_deleteRowsAtIndexPaths:withRowAnimation:
reloadRowsAtIndexPaths:withRowAnimation: mp_reloadRowsAtIndexPaths:withRowAnimation:
moveRowAtIndexPath:toIndexPath: mp_moveRowAtIndexPath:toIndexPath:
indexPathForSelectedRow: mp_indexPathForSelectedRow:
indexPathsForSelectedRows: mp_indexPathsForSelectedRows:
selectRowAtIndexPath:animated:scrollPosition: mp_selectRowAtIndexPath:animated:scrollPosition:
deselectRowAtIndexPath:animated: mp_deselectRowAtIndexPath:animated:
dequeueReusableCellWithIdentifier:forIndexPath: mp_dequeueReusableCellWithIdentifier:forIndexPath:

Example Code

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [self startLoadingFeed];
    
    MPServerAdPositioning *positioning = [[MPServerPositioning alloc] init];
    
    self.placer = [MPTableViewAdPlacer placerWithTableView:self.tableView 
                                            viewController:self 
                                             adPositioning:positioning
                                   defaultAdRenderingClass:[MPNativeAdCell class]];
    [self.placer loadAdsForAdUnitID:self.adUnitID];
}

This will ensure that an ad appears based on the settings in your ad unit settings page.


Place Ads in a UICollectionView

The MoPub SDK provides a helper class, `MPCollectionViewAdPlacer`, that handles requesting ads from MoPub and inserting them into your existing `UICollectionView` subclass. When an instance of `MPCollectionViewAdPlacer` is initialized with a collection view, it wraps the collection view’s data source and delegate in order to insert ads and adjust the positions of your regular content cells. In your `UICollectionView` feed’s `UIViewController`’s `viewDidLoad`

1. Create an `MPServerAdPositioning` object. This object informs the MPCollectionViewAdPlacer about where to place ads within the table view.

    MPServerAdPositioning *positioning = [[MPServerAdPositioning alloc] init];

2. Set up your preferred ad positioning in the MoPub UI in the ad unit settings. The `MPServerAdPositioning` object receives ad positions from those settings.

3. Instantiate your `MPCollectionViewAdPlacer` with your `UICollectionView` subclass and your `MPServerAdPositioning` object.

    self.placer = [MPCollectionViewAdPlacer placerWithCollectionView:self.collectionView viewController:self adPositioning:positioning defaultAdRenderingClass:[YourNativeAdCell class]];

`self.collectionView` is the `UICollectionView` that contains your feed. `YourNativeAdCell` is a `UICollectionViewCell` subclass that implements the `MPNativeAdRendering` protocol

    // YourNativeAdCell.h
    
    @interface YourNativeAdCell : UICollectionViewCell 
    
    @property (strong, nonatomic) UILabel *titleLabel;
    @property (strong, nonatomic) UILabel *mainTextLabel;
    @property (strong, nonatomic) UIButton *callToActionButton;
    @property (strong, nonatomic) UIImageView *iconImageView;
    @property (strong, nonatomic) UIImageView *mainImageView;
    @property (strong, nonatomic) UIImageView *daaIconImageView;
    
    @end
    
    // YourNativeAdCell.m
    
    @implementation YourNativeAdCell
    
    ...
    
    - (void)layoutAdAssets:(MPNativeAd *)adObject
    {
        [adObject loadTitleIntoLabel:self.titleLabel];
        [adObject loadTextIntoLabel:self.mainTextLabel];
        [adObject loadCallToActionTextIntoLabel:self.callToActionButton.titleLabel];
        [adObject loadIconIntoImageView:self.iconImageView];
        [adObject loadImageIntoImageView:self.mainImageView];
        [adObject loadImageIntoImageView:self.daaIconImageView]; 
    }
    
    + (CGSize)sizeWithMaximumWidth:(CGFloat)maximumWidth
    {
        return CGSizeMake(maximumWidth, kNativeAdCellHeight);
    }

    // You MUST implement this method if YourNativeAdCell uses a nib
    + (UINib *)nibForAd
    {
        return [UINib nibWithNibName:@"YourNativeAdCell" bundle:nil];
    }

    @end

4. Add targeting parameters to provide more information about your ad to the advertiser, and conserve bandwidth by getting only the right assets.

    MPNativeAdRequestTargeting *targeting = [MPNativeAdRequestTargeting targeting];
    targeting.desiredAssets = [NSSet setWithObjects:kAdIconImageKey, kAdMainImageKey, kAdCTATextKey, kAdTextKey, kAdTitleKey, nil];

See more details on passing information like location in our Data Passing doc.

5. Instruct your `MPCollectionViewAdPlacer` instance to begin loading ads and placing them into your feed, using the ad unit ID you got from the MoPub dashboard.

    [self.placer loadAdsForAdUnitID:@"YOUR_ADUNIT_ID"];

6. Replace `UICollectionView` Method Calls

Replace calls to the following `UICollectionView` methods with the MoPub SDK category equivalents.

Instead of:

    [self.collectionView selectItemAtIndexPath:myIndexPath];

Use:

    [self.collectionView mp_selectItemAtIndexPath:myIndexPath];

These methods work just like the regular `UICollectionView` methods, except that they make adjustments to the `NSIndexPath` parameters to handle the fact that your stream has extra ad items.

IMPORTANT: These replacements are mandatory. If you skip this step, you will see problems related to your content item positions being out of sync with your collection view.

ORIGINAL REPLACEMENT
setDelegate: mp_setDelegate:
delegate mp_delegate
setDataSource: mp_setDataSource:
dataSource mp_dataSource
dequeueReusableCellWithReuseIdentifier:forIndexPath: mp_dequeueReusableCellWithReuseIdentifier:forIndexPath:
indexPathsForSelectedItems mp_indexPathsForSelectedItems
selectItemAtIndexPath:animated:scrollPosition: mp_selectItemAtIndexPath:animated:scrollPosition:
deselectItemAtIndexPath:animated: mp_deselectItemAtIndexPath:animated:
reloadData mp_reloadData
layoutAttributesForItemAtIndexPath: mp_layoutAttributesForItemAtIndexPath:
indexPathForItemAtPoint: mp_indexPathForItemAtPoint:
indexPathForCell: mp_indexPathForCell:
cellForItemAtIndexPath: mp_cellForItemAtIndexPath:
visibleCells mp_visibleCells
indexPathsForVisibleItems mp_indexPathsForVisibleItems
scrollToItemAtIndexPath:atScrollPosition:animated: mp_scrollToItemAtIndexPath:atScrollPosition:animated:
insertSections: mp_insertSections:
deleteSections: mp_deleteSections:
reloadSections: mp_reloadSections:
moveSection:toSection: mp_moveSection:toSection:
insertItemsAtIndexPaths: mp_insertItemsAtIndexPaths:
deleteItemsAtIndexPaths: mp_deleteItemsAtIndexPaths:
reloadItemsAtIndexPaths: mp_reloadItemsAtIndexPaths:
moveItemAtIndexPath:toIndexPath: mp_moveItemAtIndexPath:toIndexPath:

Example Code

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [self startLoadingFeed];
    
    MPServerAdPositioning *positioning = [[MPServerAdPositioning alloc] init];

    self.placer = [MPCollectionViewAdPlacer placerWithCollectionView:self.collectionView 
                                                      viewController:self 
                                                       adPositioning:positioning                
                                             defaultAdRenderingClass:[YourNativeAdCell class]];
    [self.placer loadAdsForAdUnitID:self.adUnitID];
}

This will ensure that an ads appears based on your native ad unit settings.

Defining Ad Positions in the Client

We strongly recommend using server side positioning. However, the SDK does support setting positioning directly in the client. To set up client positioning:

1. Create an `MPClientAdPositioning` object. This object informs the MPTableViewAdPlacer about where to place ads within the table view.

    MPClientAdPositioning *positioning = [MPClientAdPositioning positioning];

2. If you want ads to appear at certain fixed positions within your feed, use `addFixedIndexPath:` to specify those `NSIndexPaths`.

    [positioning addFixedIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];

This will ensure that an ad appears at row 1 section 0 of your feed.

3. Use `enableRepeatingPositionsWithInterval:` to instruct the `MPTableViewAdPlacer` to insert ads at the specified interval as more items are loaded into your feed.

    [positioning enableRepeatingPositionsWithInterval:5];

This will ensure that an ad appears as every **5th** row in your feed. Note that repeating ads will only be inserted **after** the last fixed position ad.