Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.cloudx.io/llms.txt

Use this file to discover all available pages before exploring further.

Native ads let you render ad creatives using your own UI components — title, body, icon, media, call-to-action — in your own layout. With video creatives and the right playback settings, native ads become full-screen vertical “Reels” (the same UX as Instagram Reels or TikTok). A Reel is built from three things:
  1. A native ad with video content. The ad’s mediaView contains the video player. Other assets (title, body, icon, CTA) are overlaid on top.
  2. Video playback settings. Three properties on the loader disable fullscreen, start the video with sound, and hide media controls.
  3. A full-screen paging container. A UICollectionView with pagingEnabled = YES and a vertical flow layout. Each cell is one Reel.

Reels API Surface

CapabilityCloudX APIDescription
Detect video creativead.nativeAd.isVideoContentReturns YES when the loaded creative is a video
Get video durationad.nativeAd.videoDurationDuration of the video in seconds (0 if unknown)
Ad dismissed by userdidCloseNativeAd: delegate callbackFires when the user reports or hides the ad via AdChoices
Disable fullscreenloader.disableVideoFullScreen = YESPrevents the video from entering fullscreen on tap
Start unmutedloader.startVideoUnmuted = YESStarts playback with sound on
Hide media controlsloader.hideVideoMediaControls = YESHides play/pause and mute/unmute controls
The Reels video playback settings are adapter-dependent. In CloudX iOS SDK 3.4.0, they are honored by Meta native video creatives.
Native-ad adapter support and dependencies are documented on the adapter pages.

Create a Loader and Configure Video

@interface YourViewController () <CLXNativeAdDelegate, CLXAdRevenueDelegate>
@property (nonatomic, strong) CLXNativeAdLoader *nativeAdLoader;
@end

@implementation YourViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.nativeAdLoader = [[CloudXCore shared] createNativeAdLoaderWithAdUnitIdentifier:@"your-native-ad-unit-id"];
    self.nativeAdLoader.nativeAdDelegate = self;
    self.nativeAdLoader.revenueDelegate = self;

    self.nativeAdLoader.disableVideoFullScreen = YES;
    self.nativeAdLoader.startVideoUnmuted = YES;
    self.nativeAdLoader.hideVideoMediaControls = YES;
}

- (void)dealloc {
    [self.nativeAdLoader destroy];
}

@end
PropertyDefaultReels ValueDescription
disableVideoFullScreenNOYESPrevents the video from entering fullscreen when tapped
startVideoUnmutedNOYESStarts video playback with sound on
hideVideoMediaControlsNOYESHides play/pause and mute/unmute controls
Set these properties before calling loadAd. They are ignored for static image creatives. For a Reels-style feed, set all three to YES.

Build a Native Ad Layout

Create a CLXNativeAdView using a view binder that maps your custom subviews to asset roles:
- (CLXNativeAdView *)createNativeAdView {
    CLXNativeAdViewBinder *binder = [[CLXNativeAdViewBinder alloc] initWithBuilderBlock:^(CLXNativeAdViewBinderBuilder *builder) {
        builder.titleLabelTag = CLXNativeAdViewTagTitleLabel;
        builder.bodyLabelTag = CLXNativeAdViewTagBodyLabel;
        builder.iconImageViewTag = CLXNativeAdViewTagIconImageView;
        builder.callToActionButtonTag = CLXNativeAdViewTagCallToActionButton;
        builder.mediaContentViewTag = CLXNativeAdViewTagMediaViewContainer;
        builder.optionsContentViewTag = CLXNativeAdViewTagOptionsContentView;
        builder.advertiserLabelTag = CLXNativeAdViewTagAdvertiserLabel;
    }];

    CLXNativeAdView *adView = [[CLXNativeAdView alloc] init];
    [adView bindViewsWithViewBinder:binder];
    return adView;
}
Alternatively, set outlets directly on the CLXNativeAdView:
CLXNativeAdView *adView = [[CLXNativeAdView alloc] init];
adView.titleLabel = myTitleLabel;
adView.bodyLabel = myBodyLabel;
adView.iconImageView = myIconImageView;
adView.callToActionButton = myCTAButton;
adView.mediaContentView = myMediaContainer;
adView.optionsContentView = myOptionsContainer;
adView.advertiserLabel = myAdvertiserLabel;

Load the Ad

Flow A — Load into a pre-built view:
CLXNativeAdView *adView = [self createNativeAdView];
[self.nativeAdLoader loadAdIntoAdView:adView];
Flow B — Load first, render later (deferred rendering):
[self.nativeAdLoader loadAd];

- (void)didLoadNativeAd:(nullable CLXNativeAdView *)nativeAdView forAd:(CLXAd *)ad {
    CLXNativeAdView *adView = /* create your ad view */;
    [self.nativeAdLoader renderNativeAdView:adView withAd:ad];
    [self.view addSubview:adView];
}

Handle Callbacks

#pragma mark - CLXNativeAdDelegate (Required)

- (void)didLoadNativeAd:(nullable CLXNativeAdView *)nativeAdView forAd:(CLXAd *)ad {
    NSLog(@"Native ad loaded from %@", ad.networkName);

    if (ad.nativeAd.isVideoContent) {
        NSLog(@"Video duration: %.1fs", ad.nativeAd.videoDuration);
    }

    if (nativeAdView) {
        [self.view addSubview:nativeAdView];
    }
}

- (void)didFailToLoadNativeAdForAdUnitIdentifier:(NSString *)adUnitId error:(CLXError *)error {
    NSLog(@"Native ad failed to load: %@", error.localizedDescription);
}

- (void)didClickNativeAd:(CLXAd *)ad {
    NSLog(@"Native ad clicked");
}

#pragma mark - CLXNativeAdDelegate (Optional)

- (void)didExpireNativeAd:(CLXAd *)ad {
    NSLog(@"Native ad expired — destroy and reload");
    [self.nativeAdLoader destroyAd:ad];
    [self.nativeAdLoader loadAd];
}

- (void)didCloseNativeAd:(CLXAd *)ad {
    NSLog(@"User dismissed the ad via AdChoices");
    [self.nativeAdLoader destroyAd:ad];
}

#pragma mark - CLXAdRevenueDelegate

- (void)didPayRevenueForAd:(CLXAd *)ad {
    NSLog(@"Native ad revenue: %@ from %@", ad.revenue, ad.networkName);
}

Clean Up

Always destroy ads when you’re done with them:
// Destroy a specific loaded ad
[self.nativeAdLoader destroyAd:ad];

// Destroy the loader and all associated resources
[self.nativeAdLoader destroy];

Native Ad Assets (CLXNativeAd)

The CLXNativeAd object is available via ad.nativeAd in delegate callbacks:
PropertyTypeDescription
titleNSString?Headline text
bodyNSString?Body / description text
callToActionNSString?CTA button text (e.g., “Install Now”)
advertiserNSString?Advertiser name
iconCLXNativeAdImage?App icon image
mainImageCLXNativeAdImage?Main image (static creatives)
mediaViewUIView?Video/media player view (adapter-provided)
optionsViewUIView?AdChoices or options view (adapter-provided)
mediaContentAspectRatioCGFloatAspect ratio of the media content
starRatingNSNumber?App store rating (0–5)
isVideoContentBOOLWhether the creative is a video
videoDurationNSTimeIntervalVideo length in seconds (0 if unknown)
expiredBOOLWhether the ad has expired

Reels Feed Tips

  • Use a UICollectionView with pagingEnabled = YES and a vertical UICollectionViewFlowLayout with minimumLineSpacing = 0. Each cell should be full-screen.
  • Call prepareForReuse on the CLXNativeAdView when recycling cells.
  • Create one CLXNativeAdLoader per slot. Load ads sequentially.
  • Destroy ads when no longer needed via destroyAd:.