Native Ad

1. Basic requirements

  • Add ​ADX iOS SDK to your project.

  • Use the Ad Unit ID issued for Native Ads.

  • Before requesting an ad, SDK initialization must be done first.

    • SDK initialization should be called only once when the app launches and ad requests should be made after SDK initialization is complete.

    • For iOS 14 and later, request ads only after obtaining ATT (App Tracking Transparency) permission.

2. Layout setup

For Native Ads, you must create the layout for the ad yourself. The required elements are as follows:

  • Title : UILabel

  • Main Text : UILabel

  • Call-To-Action : UIButton

  • Icon Image : UIImageView

  • Main Image : UIImageView

  • Privacy Icon : UIImageView

  • Ad Tag : UIView (UILabel or UIImageView)

The Ad Tag element must include a UI component that displays the text “Ad” or “Advertisement” to clearly indicate to users that it is an advertisement. Failure to include this element may result in ad delivery being suspended by some ad networks.

All of these elements must be included and properly configured, and no view should cover the ad content. Additionally, ensure that ad content is not modified or tampered with in any way, such as changing text, replacing images, or altering actions triggered by user interactions.

// NativeAdView.h

#import <ADXLibrary/ADXNativeAdRendering.h>

@interface NativeAdView : UIView <ADXNativeAdRendering>
        
@property (nonatomic, weak) IBOutlet UILabel *titleLabel;
@property (nonatomic, weak) IBOutlet UILabel *mainTextLabel;
@property (nonatomic, weak) IBOutlet UIButton *callToActionButton;
@property (nonatomic, weak) IBOutlet UIImageView *iconImageView;
@property (nonatomic, weak) IBOutlet UIImageView *mainImageView;
@property (nonatomic, weak) IBOutlet UIImageView *privacyInformationIconImageView;
        
@end

// NativeAdView.m

@implementation NativeAdView

- (void)layoutSubviews {
    [super layoutSubviews];
}

- (UILabel *)nativeMainTextLabel {
    return self.mainTextLabel;
}

- (UILabel *)nativeTitleTextLabel {
    return self.titleLabel;
}

- (UIButton *)nativeCallToActionButton {
    return self.callToActionButton;
}

- (UILabel *)nativeSponsoredByCompanyTextLabel {
    return self.sponsoredByLabel;
}

- (UIImageView *)nativeIconImageView {
    return self.iconImageView;
}

- (UIImageView *)nativeMainImageView {
    return self.mainImageView;
}

- (UIImageView *)nativePrivacyInformationIconImageView {
    return self.privacyInformationIconImageView;
}

@end

3. Implementation

Native Ads can be loaded using one of the following two methods:

Case 1: When using a single View

  1. Configure the RenderingViewClass using the setRenderingViewClass:renderingViewClass: method of ADXNativeAdFactory.

  2. Register the ADXNativeAdFactoryDelegate callbacks.

  3. Call loadAd on the ADXNativeAdFactoryDelegate to load the ad.

  4. Once the ad is loaded successfully, the onSuccess:nativeAd: callback of ADXNativeAdFactoryDelegate will be invoked.

#import "NativeAdViewController"
#import "NativeAdView.h"

#import <ADXLibrary/ADXNativeAdFactory.h>

@interface NativeAdViewController () <ADXNativeAdFactoryDelegate, ADXNativeAdDelegate>

@property (strong) ADXNativeAd *nativeAd;

@end

@implementation NativeAdViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [[ADXNativeAdFactory sharedInstance] 
        setRenderingViewClass:@"<ADX_NATIVE_AD_UNIT_ID>" 
        renderingViewClass:[NativeAdView class]];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [[ADXNativeAdFactory sharedInstance] addDelegate:self];
    [[ADXNativeAdFactory sharedInstance] loadAd:@"<ADX_NATIVE_AD_UNIT_ID>"];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[ADXNativeAdFactory sharedInstance] removeDelegate:self];
}

#pragma mark - ADXNativeAdFactoryDelegate

- (void)onSuccess:(NSString *)adUnitId nativeAd:(ADXNativeAd *)nativeAd {
    NSLog(@"onSuccess : %@", adUnitId);

    if([adUnitId isEqualToString:ADX_NATIVE_AD_UNIT_ID]) {
        self.nativeAd = nativeAd;
        self.nativeAd.delegate = self;

        UIView *nativeAdView = [[ADXNativeAdFactory sharedInstance] 
            getNativeAdView:@"<ADX_NATIVE_AD_UNIT_ID>"];

        nativeAdView.frame = CGRectMake(0.0,
                                        100.0,
                                        320.0,
                                        300.0);
        [self.view addSubview:nativeAdView];
    }
}

- (void)onFailure:(NSString *)adUnitId {
    NSLog(@"onFailure : %@", adUnitId);
}

#pragma mark - ADXNativeAdDelegate

- (UIViewController *)viewControllerForPresentingModalView {
    return self;
}

@end

Case 2: Using AdPlacer with UITableView / UICollectionView

  1. Configure the RenderingViewClass using the setRenderingViewClass:renderingViewClass: method of ADXNativeAdFactory.

  2. Set the size of the ad to be loaded.

    • The ad size should be specified either in the XIB file or by setting the frame programmatically.

  3. Use ADXAdPositioning to specify fixed and repeating ad positions:

    • addFixedIndexPath: – specify fixed ad positions

    • enableRepeatingPositionsWithInterval: – specify repeating ad positions

  4. Call loadAdsForAdUnitID: to load the ads.

#import "NativeAdPlacerViewController.h"
#import "NativeAdView.h"

#import <ADXLibrary/ADXNativeAdFactory.h>

@interface NativeAdPlacerViewController () <UICollectionViewDataSource, UICollectionViewDelegate, ADXCollectionViewAdPlacerDelegate>

@property (weak) IBOutlet UICollectionView *colltionView;
@property (strong) ADXCollectionViewAdPlacer *placer;

@end

@implementation NativeAdPlacerViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [[ADXNativeAdFactory sharedInstance] 
        setRenderingViewClass:@"<ADX_NATIVE_AD_UNIT_ID>" 
        renderingViewClass:[NativeAdView class]];
    
    ADXAdPositioning *adPositioning = [ADXAdPositioning positioning];
    [adPositioning addFixedIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
    [adPositioning enableRepeatingPositionsWithInterval:3];
    
    self.placer = [[ADXNativeAdFactory sharedInstance] 
        getCollectionViewAdPlacer:@"<ADX_NATIVE_AD_UNIT_ID>"
        collectionView:self.colltionView
        viewController:self
        adPositioning:adPositioning];
        
    [self.placer loadAdsForAdUnitID:@"<ADX_NATIVE_AD_UNIT_ID>"];
}

Since cell positions may change, please refer to ADXTableViewAdPlacer.h for UITableView or ADXCollectionViewAdPlacer.h for UICollectionView, and use the provided methods accordingly.

4. Ad Revenue (paidEventHandler)

You can check the estimated ad revenue for ad impressions.

  • As shown in the example below, use paidEventHandler to check the estimated eCPM value.

  • Manually set values during mediation setup and actual values may be mixed, so it is recommended to treat this as an estimate.

  • The currency unit of eCPM is USD.

  • You can link ad revenue data with your MMP. For details, please refer to the SDK integration guides below:

#import <UIKit/UIKit.h>
#import <ADXLibrary/ADXNativeAdFactory.h>
#import "NativeAdViewController.h"
#import "NativeAdView.h"
#import <FirebaseAnalytics/FirebaseAnalytics.h>
#import <AppsFlyerAdRevenue/AppsFlyerAdRevenue.h>

@interface NativeAdViewController () <ADXNativeAdFactoryDelegate, ADXNativeAdDelegate>
@property (nonatomic, strong) ADXNativeAd *nativeAd;
@end

@implementation NativeAdViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [[ADXNativeAdFactory sharedInstance] 
        setRenderingViewClass:@"<ADX_NATIVE_AD_UNIT_ID>" 
        renderingViewClass:[NativeAdView class]];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [[ADXNativeAdFactory sharedInstance] addDelegate:self];
    [[ADXNativeAdFactory sharedInstance] loadAd:@"<ADX_NATIVE_AD_UNIT_ID>"];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];    
    [[ADXNativeAdFactory sharedInstance] removeDelegate:self];
}

- (void)handleAdRevenue:(NSNumber *)revenue {
    // 1) Firebase Analytics
    [FIRAnalytics logEventWithName:kFIREventAdImpression
                        parameters: @{
        kFIRParameterAdPlatform: @"AD(X)",
        kFIRParameterAdFormat: @"NativeAd",
        kFIRParameterAdUnitName: @"ADX Native Ad",
        kFIRParameterCurrency: @"USD",
        kFIRParameterValue: revenune
    }];
    
    // 2) AppsFlyer
    NSDictionary * adRevenueParams = @{
        @"AdUnitName" : @"ADX Native Ad",
        @"AdType" : @"NativeAd",
    };
    
    AppsFlyerAdRevenue * appsFlyerAdRevenue = [AppsFlyerAdRevenue shared];
    [appsFlyerAdRevenue 
        logAdRevenueWithMonetizationNetwork:@"AD(X)"
        mediationNetwork:AppsFlyerAdRevenueMediationNetworkTypeCustom
        eventRevenue:revenune
        revenueCurrency:@"USD"
        additionalParameters:adRevenueParams];
}

#pragma mark - ADXNativeAdFactoryDelegate

- (void)onSuccess:(NSString *)adUnitId nativeAd:(ADXNativeAd *)nativeAd {
    NSLog(@"onSuccess : %@", adUnitId);

    if([adUnitId isEqualToString:@"<ADX_NATIVE_AD_UNIT_ID>"]) {
        self.nativeAd = nativeAd;
        self.nativeAd.delegate = self;
        
        __weak typeof(self) weakSelf = self;
        self.nativeAd.paidEventHandler = ^(double eCPM) {
            __strong typeof(self) strongSelf = weakSelf;
            if(!strongSelf) { return; }
            NSNumber * revenue = [NSNumber numberWithDouble:eCPM/1000];
            [strongSelf handleAdRevenue:revenue];
        };

        UIView *nativeAdView = [[ADXNativeAdFactory sharedInstance] 
            getNativeAdView:@"<ADX_NATIVE_AD_UNIT_ID>"];

        nativeAdView.frame = CGRectMake(0.0,
                                        100.0,
                                        320.0,
                                        300.0);
        [self.view addSubview:nativeAdView];
    }
}

- (void)onFailure:(NSString *)adUnitId {
    NSLog(@"onFailure : %@", adUnitId);
}

#pragma mark - ADXNativeAdDelegate

- (UIViewController *)viewControllerForPresentingModalView {
    return self;
}

@end

Last updated

Was this helpful?