Native Ads Integration for iOS

Native ads are a form of advertising that you can customize to blend in with the other content in your app. This makes ads appear more organic, which leads to a better user experience and higher retention.

Before you start

Make sure you have correctly integrated the ironSource SDK 8.4.0+ into your application. Integration is outlined here.

To integrate native ads, you need to follow these five steps

  1. Create and Load a native ad object
  2. Implement the Delegate
  3. Design a view and bind it
  4. Show the native ad
  5. Destroy the native ad

Step 1. Create and Load a native ad object

  1. Create a native ad object using the LevelPlayNativeAdBuilder class, which allows for custom configuration of the object. We advise creating a separate class to manage your native ads loading mechanism in a single place.
    LevelPlayNativeAd *levelPlayNativeAd = [[[[LevelPlayNativeAdBuilder new] 
    withViewController:self] 
    withPlacementName:YOUR_PLACEMENT_NAME] // Replace with your placement or leave empty
    withDelegate:self]	// We implement the delegate in step 2
    .build;
    
    let levelPlayNativeAd: LevelPlayNativeAd = LevelPlayNativeAdBuilder()
                .withViewController(self)
                .withPlacementName(YOUR_PLACEMENT_NAME) // Replace with your placement or leave empty
                .withDelegate(self)
                .build()
    

    Note: Make sure to create a native ad a shortly before presenting it to your users, as the loading process may require some time. It is not recommended to make consecutive requests in a short span, as the likelihood of availability changes is low.

  2. Once you’ve built the ad object, load the native ad and create a new view of type NativeAdView. You will be notified when the ad is loaded through the didLoad callback of the delegate.
    [levelPlayNativeAd loadAd];
    NativeAdView *levelPlayNativeAdView = [[NativeAdView alloc] init];
    
    levelPlayNativeAd.load()
    let levelPlayNativeAdView = NativeAdView()
    

    We recommend keeping references to the native ad and its corresponding views. These references will be used to populate the view once the didLoad callback is triggered.
    @property (nonatomic, strong) LevelPlayNativeAd *nativeAd;
    @property (nonatomic, strong) NativeAdView  *nativeAdView;  //We define NativeAdView in step 3
    private var nativeAd: LevelPlayNativeAd!
    private var nativeAdView: NativeAdView! //We define NativeAdView in step 3

    Make sure to maintain these references after the ad has loaded and the view is initialized.

       _nativeAd = levelPlayNativeAd;
       _nativeAdView = levelPlayNativeAdView;
      nativeAd = levelPlayNativeAd    
      nativeAdView = levelPlayNativeAdView

Step 2. Implement the Delegate

Next, implement the LevelPlayNativeAdDelegate in your code. The LevelPlay SDK fires several callbacks to inform you of native ad activity. The SDK will notify your Listener of all the events listed below:

// LevelPlayNativeAdDelegate
/**
 Called after a native ad has been successfully loaded
 @param nativeAd Level Play native ad.
 @param adInfo The info of the ad.
 */
-(void)didLoad:(LevelPlayNativeAd *)nativeAd
    withAdInfo:(ISAdInfo *)adInfo{}
/**
 Called after a native has attempted to load an ad but failed.
 @param nativeAd Level Play native ad.
 @param error The reason for the error
 */
-(void)didFailToLoad:(LevelPlayNativeAd *)nativeAd
           withError:(NSError *)error;{}
/**
 Called after a native ad impression has been recorded.
 @param nativeAd Level Play native ad.
 @param adInfo The info of the ad.
 */
-(void)didRecordImpression:(LevelPlayNativeAd *)nativeAd
                withAdInfo:(ISAdInfo *)adInfo{}
/**
 Called after a native ad has been clicked.
 @param nativeAd Level Play native ad.
 @param adInfo The info of the ad.
 */
-(void)didClick:(LevelPlayNativeAd *)nativeAd
     withAdInfo:(ISAdInfo *)adInfo;{}
// LevelPlayNativeAdDelegate
/**
 Called after a native ad has been successfully loaded
 @param nativeAd Level Play native ad.
 @param adInfo The info of the ad.
 */ 
func didLoad(_ nativeAd: LevelPlayNativeAd, with adInfo: ISAdInfo) {}
/**
 Called after a native has attempted to load an ad but failed.
 @param nativeAd Level Play native ad.
 @param error The reason for the error
 */    
func didFail(_ nativeAd: LevelPlayNativeAd, withError error: Error) {}
 
/**
 Called after a native ad impression has been recorded.
 @param nativeAd Level Play native ad.
 @param adInfo The info of the ad.
 */   
func didRecordImpression(_ nativeAd: LevelPlayNativeAd, with adInfo: ISAdInfo) {}
   
/**
 Called after a native ad has been clicked.
 @param nativeAd Level Play native ad.
 @param adInfo The info of the ad.
 */ 
func didClick(_ nativeAd: LevelPlayNativeAd, with adInfo: ISAdInfo) {}
Note: The native ad object created for loading and the object returned in the callbacks refer to the same native ad object.

Step 3. Design a native ad view and bind it

You are required to create a new view, bind it, and set all relevant information manually before loading the native ad. This includes arranging the different assets like below.

  1. Download and import the following view (.xib) file into the project, and ensure adding it to your project’s target. The file contains the views that will hold the native ad assets. Use the Interface Builder to customize the components according to your app’s design.
    Note: While modifying the .xib file, avoid disconnecting the components from their predefined outlets.

    The design includes the following components:
    • View #1: adAppIcon (UIImageView)
    • View #2: adTitleView (UILabel)
    • View #3: adAdvertiserView (UILabel)
    • View #4: adBodyView (UILabel)
    • View #5: adMediaView (UIView with custom class LevelPlayMediaView
    • View #6: adCallToActionView (UIButton)
  2. Next, create a custom class to represent the view by inheriting from UIView:

    #import <IronSource/IronSource.h>
    @interface NativeAdView : UIView
    @property (nonatomic, strong) ISNativeAdView *nativeAdView;
    - (void)populateWithContent:(nonnull LevelPlayNativeAd *)nativeAd;
    @end
    @implementation NativeAdView
    - (instancetype)init {
        UINib *nib = [UINib nibWithNibName:@"ISNativeAdView" bundle:[NSBundle mainBundle]];
        
        NSArray *nibContents = [nib instantiateWithOwner:nil options:nil];
        self.nativeAdView = (NativeAdView *)[nibContents firstObject];
        self.translatesAutoresizingMaskIntoConstraints = NO;
        self.nativeAdView.translatesAutoresizingMaskIntoConstraints = NO;
        
        // adding your own ad badge, privacy icon, or delete button here
      // ...
        return self;
    }
    // This function will be useful once the didLoad call back arrives
    - (void)populateWithContent:(nonnull LevelPlayNativeAd *)nativeAd {
        // Assigning views contents to the nativeAdView
        if (nativeAd.icon.image) {
            self.nativeAdView.adAppIcon.image = nativeAd.icon.image;
        } else {
            [self.nativeAdView.adAppIcon removeFromSuperview];
        }
        if (nativeAd.title) {
            self.nativeAdView.adTitleView.text = nativeAd.title;
        }
        if (nativeAd.advertiser) {
            self.nativeAdView.adAdvertiserView.text = nativeAd.advertiser;
        }
        if (nativeAd.body) {
            self.nativeAdView.adBodyView.text = nativeAd.body;
        }
        if (nativeAd.callToAction) {
            [self.nativeAdView.adCallToActionView setTitle:nativeAd.callToAction forState:UIControlStateNormal];
        // To ensure proper processing of touch events by the SDK, user interaction should be disabled
            self.nativeAdView.adCallToActionView.userInteractionEnabled = NO;
        }
        // call function to register native ad
        [self.nativeAdView registerNativeAdViews:nativeAd];
    }
    @end
    
    import UIKit
    import IronSource
    class NativeAdView: UIView {
        private var nativeAdView: ISNativeAdView!
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            let nib = UINib(nibName: "ISNativeAdView", bundle: .main)
            
            let nibContents = nib.instantiate(withOwner: nil, options: nil)
            self.nativeAdView = nibContents.first as? ISNativeAdView ?? ISNativeAdView()
            
            self.translatesAutoresizingMaskIntoConstraints = false
            self.nativeAdView?.translatesAutoresizingMaskIntoConstraints = false
            
            // adding your own ad badge, privacy icon, or delete button here
            // ...
            addSubview(nativeAdView)
        }
        
        required init?(coder: NSCoder) {
            super.init(coder: coder)
        }
        // This function will be useful once the didLoad call back arrives
        func populateWithContent(nativeAd: LevelPlayNativeAd) {
            // Assigning views contents to the nativeAdView
            if let iconImage = nativeAd.icon?.image {
                nativeAdView.adAppIcon?.image = iconImage
            } else {
                nativeAdView.adAppIcon?.removeFromSuperview()
            }
            nativeAdView.adTitleView?.text = nativeAd.title
            nativeAdView.adAdvertiserView?.text = nativeAd.advertiser
            nativeAdView.adBodyView?.text = nativeAd.body
            nativeAdView.adCallToActionView?.setTitle(nativeAd.callToAction, for: .normal)
            nativeAdView.adCallToActionView?.isUserInteractionEnabled = false
            // call function to register native ad
            nativeAdView.registerNativeAdViews(nativeAd)
        }
    }
    

MediaView 

The MediaView is a designated container that is intended to display the main media element. It is recommended to use fixed size constraints for the container.

Enhancing ad transparency

Privacy icon – This element should be incorporated into the bottom left corner of your native ad during the design process.

Ad indication – To make sure your users understand that this is an ad, you’re required to mark your native ads as “Ad”. This can be achieved by adding your own indication.

Step 4. Show the Native Ad

Create a container view and bind it to a reference in your code. This view will be the parent view for the native ad view.

@property (weak, nonatomic) IBOutlet UIView   *nativeAdContainer;
@IBOutlet weak var nativeAdContainer: UIView!

When the didLoad callback arrives, populate the view with the ad’s content and assign it as a subview for the container view:
-(void)didLoad:(LevelPlayNativeAd *)nativeAd
    withAdInfo:(ISAdInfo *)adInfo{
        // Populate view
        [_nativeAdView populateWithContent:nativeAd];
    
        // Nest the native ad view in the container view
        [_nativeAdContainer addSubview:_nativeAdView];
    
        // Set the constraints between the container and native ad view
        _nativeAdView.translatesAutoresizingMaskIntoConstraints = NO;
        [NSLayoutConstraint activateConstraints:@[
            [_nativeAdView.topAnchor constraintEqualToAnchor:_nativeAdContainer.topAnchor],
            [_nativeAdView.leadingAnchor constraintEqualToAnchor:_nativeAdContainer.leadingAnchor],
            [_nativeAdView.trailingAnchor constraintEqualToAnchor:_nativeAdContainer.trailingAnchor],
            [_nativeAdView.bottomAnchor constraintEqualToAnchor:_nativeAdContainer.bottomAnchor]
        ]];
}
func didLoad(_ nativeAd: LevelPlayNativeAd, with adInfo: ISAdInfo) {
        // Populate view
        nativeAdView.populateWithContent(nativeAd: nativeAd)
        
        // Nest the native ad view in the container view
        nativeAdContainer.addSubview(nativeAdView)
        
        // Set the constraints between the container and native ad view
        nativeAdView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            nativeAdView.topAnchor.constraint(equalTo: nativeAdContainer.topAnchor),
            nativeAdView.leadingAnchor.constraint(equalTo: nativeAdContainer.leadingAnchor),
            nativeAdView.trailingAnchor.constraint(equalTo: nativeAdContainer.trailingAnchor),
            nativeAdView.bottomAnchor.constraint(equalTo: nativeAdContainer.bottomAnchor)
        ])
    }

Important! Once you’ve successfully completed step 4, a native ad will be presented to the user. Follow Step 1 again to request a new LevelPlayNativeAd object and a NativeAdView.

Step 5. Destroy the Native Ad

To destroy a native ad, call destroyAd and remove it from the container view.

[_nativeAd destroyAd];
[_nativeAdView removeFromSuperview];
nativeAd.destroy()
nativeAdView.removeFromSuperview()

A destroyed native ad can no longer be loaded. If you want to serve it again, you must initiate it once more.

Done!
You can now deliver Native Ads through LevelPlay.