Search...
Menu

Native Ads

💡Tips

  • 🚀 Use preloading mechanism to enhance UX
  • ⚠️ Handle lifecycle properly to prevent memory leaks
  • 🔧 Recommended to use standardized callback workflow

objective-c Copy
#import <MCSDK/MCSDK.h>
@interface SelfRenderVC () <MCNativeAdDelegate, MCAdRevenueDelegate>

@property (nonatomic, strong) MCNativeAdLoader * nativeAdLoader;
@property (nonatomic, strong) MCNativeAdView   * nativeAdView;
@property (nonatomic, strong) MCAdInfo         * adInfo;
@property (nonatomic, assign) NSInteger          retryAttempt;

@end

@implementation SelfRenderVC

#define Native_SelfRender_PlacementID @"your mediation unit id"

//Scene ID
#define Native_SelfRender_SceneID @""

#pragma mark - Load Ad
- (void)loadAd {
    if (!self.nativeAdLoader) {
        MCNativeAdLoader *nativeAdLoader = [[MCNativeAdLoader alloc] initWithPlacementId:Native_SelfRender_PlacementID];
        self.nativeAdLoader = nativeAdLoader;
    }
    self.nativeAdLoader.delegate = self;
    self.nativeAdLoader.revenueDelegate = self;
    self.nativeAdLoader.placement = Native_SelfRender_SceneID;

    [self.nativeAdLoader loadAd];
}

#pragma mark - MCNativeAdDelegate
// Ad load success
- (void)didLoadNativeAd:(nullable MCNativeAdView *)nativeAdView forAd:(MCAdInfo *_Nonnull)ad {
    // For self-rendering, you need to create MCNativeAdView
    if (!ad.nativeAd.isTemplate) {
        CGFloat scale = 4.0/3.0;
        CGFloat viewW = CGRectGetWidth([UIScreen mainScreen].bounds);
        CGFloat viewH = viewW/scale;
        _nativeAdView = [[MCNativeAdView alloc] initWithFrame:CGRectMake(0, 0, viewW, viewH)];
    } else {
        _nativeAdView = nativeAdView;
    }
    
    _adInfo = ad;
    
    // Reset retry attempt
    self.retryAttempt = 0;
}

// Ad load failure
- (void)didFailToLoadNativeAdWithError:(MCError *_Nonnull)error {  
    // We recommends that you retry with exponentially higher delays up to a maximum delay (in this case 8 seconds) or the maximum number of retries (in this case 3)
    if (self.retryAttempt >= 3) {
        return;
    }
    self.retryAttempt++;
     
    NSInteger delaySec = pow(2, MIN(3, self.retryAttempt));

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delaySec * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [self.nativeAdLoader loadAd];
    });
}

// Ad display success
- (void)didDisplayAd:(MCAdInfo *_Nonnull)ad {

}

// Ad closed
- (void)didHideAd:(MCAdInfo *)ad {
    //pre-load
    [self.nativeAdLoader loadAd];
}

// Ad display failure
- (void)didFailToDisplayAd:(MCAdInfo *)ad withError:(MCError *)error {
    //pre-load
    [self.nativeAdLoader loadAd];
}

// Ad click
- (void)didClickNativeAd:(MCAdInfo *_Nonnull)ad {

}

#pragma mark - MCAdRevenueDelegate
// Revenue tracking
- (void)didPayRevenueForAd:(MCAdInfo *)ad {

}

For self-rendering, please refer toDemo-SelfRenderVC.m

objective-c Copy
BOOL isready = self.nativeAdView ? YES : NO;

if (!isready) {
    return;
}

ATNativeSelfRenderView *selfRenderView = [[ATNativeSelfRenderView alloc] initWithAdInfo:self.adInfo];
selfRenderView.backgroundColor = randomColor;
selfRenderView.frame = self.nativeAdView.frame;
self.nativeSelfRenderView = selfRenderView;

NSMutableArray *array = [@[selfRenderView.iconImageView,
                           selfRenderView.titleLabel,
                           selfRenderView.textLabel,
                           selfRenderView.ctaLabel,
                           selfRenderView.mainImageView] mutableCopy];
[self.nativeAdView registerClickableViewArray:array];

MCNativePrepareInfo *nativePrepareInfo = [MCNativePrepareInfo loadPrepareInfo:^(MCNativePrepareInfo * _Nonnull prepareInfo) {
    prepareInfo.textLabel = selfRenderView.textLabel;
    prepareInfo.advertiserLabel = selfRenderView.advertiserLabel;
    prepareInfo.titleLabel = selfRenderView.titleLabel;
    prepareInfo.ratingLabel = selfRenderView.ratingLabel;
    prepareInfo.iconImageView = selfRenderView.iconImageView;
    prepareInfo.mainImageView = selfRenderView.mainImageView;
    prepareInfo.dislikeButton = selfRenderView.dislikeButton;
    prepareInfo.ctaLabel = selfRenderView.ctaLabel;
    prepareInfo.domainLabel = selfRenderView.domainLabel;
    prepareInfo.warningLabel = selfRenderView.warningLabel;
    prepareInfo.mediaView = selfRenderView.mediaView;
}];
[self.nativeAdView prepareWithNativePrepareInfo:nativePrepareInfo];

[self.nativeAdLoader rendererWithNativeAdView:self.nativeAdView selfRenderView:selfRenderView adInfo:self.adInfo];

ATNativeShowViewController *showVc = [[ATNativeShowViewController alloc] initWithAdView:self.nativeAdView];
[self.navigationController pushViewController:showVc animated:YES];
self.hasShowAD = YES;

For template rendering, please refer toDemo-ExpressVC.m

objective-c Copy
BOOL isready = self.nativeAdView ? YES : NO;

if (!isready) {
    return;
}

ATNativeShowViewController *showVc = [[ATNativeShowViewController alloc] initWithAdView:self.nativeAdView];
[self.navigationController pushViewController:showVc animated:YES];
self.hasShowAD = YES;

3. Resource Release

objective-c Copy
- (void)destroy {
    if (_adInfo) {
        [self showLog:[NSString stringWithFormat:@"destroy:%@", _adInfo.mediationPlacementId]];
        [self.nativeAdLoader destroyAd];
        _nativeAdView = nil;
        _adInfo = nil;
    }
}

4. Customized Parameter Configuration

objective-c Copy
- (void)loadAd {
    MCNativeAdLoader *nativeAdLoader = [[MCNativeAdLoader alloc] initWithPlacementId:self.placementID];
    nativeAdLoader.delegate = self;
    nativeAdLoader.revenueDelegate = self;
    
    [nativeAdLoader setLoadExtraParameter:@{
        @"userData": @"test_userData"
    }];
    
    [nativeAdLoader setExtraParameter:@{
        @"test_extra_key": @"test_extra_value"
    }];
    
    [nativeAdLoader loadAd];
    self.nativeAdLoader = nativeAdLoader;
}

- (void)didLoadAd:(MCAdInfo *)ad {
    // Retrieve customized parameters
    NSString *originDataJsonString = ad.originData;
}
Previous
Splash Ads
Next
Banner Ads
Last modified: 2025-06-26Powered by