跳转到主要内容

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.

原生广告允许您使用自定义 UI 组件(标题、正文、图标、媒体、行动号召)按自己的布局渲染广告素材。配合视频素材和正确的播放设置,原生广告即可成为全屏垂直 “Reels”(与 Instagram Reels 或 TikTok 相同的用户体验)。 一个 Reel 由三部分构成:
  1. 包含视频内容的原生广告。 广告的 mediaView 包含视频播放器,其他素材(标题、正文、图标、CTA)覆盖在视频之上。
  2. 视频播放设置。 加载器上的三个属性分别用于禁用全屏、开启有声播放和隐藏媒体控件。
  3. 全屏分页容器。 启用分页的 UICollectionView 配合垂直流布局,每个单元格即为一个 Reel。

Reels API 概览

功能CloudX API说明
检测视频素材ad.nativeAd.isVideoContent当加载的素材为视频时返回 YES
获取视频时长ad.nativeAd.videoDuration视频时长(秒),未知时为 0
用户关闭广告didCloseNativeAd: 代理回调当用户通过 AdChoices 举报或隐藏广告时触发
禁用全屏loader.disableVideoFullScreen = YES阻止视频在点击时进入全屏模式
有声播放loader.startVideoUnmuted = YES开始播放时开启声音
隐藏媒体控件loader.hideVideoMediaControls = YES隐藏播放/暂停和静音/取消静音控件
Reels 视频播放设置依赖具体适配器。在 CloudX iOS SDK 3.4.0 中,这些设置由 Meta 原生视频素材支持。
原生广告适配器支持情况和依赖要求记录在各适配器页面中。

创建加载器并配置视频

@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
属性默认值Reels 值说明
disableVideoFullScreenNOYES阻止视频在点击时进入全屏模式
startVideoUnmutedNOYES开始播放时开启声音
hideVideoMediaControlsNOYES隐藏播放/暂停和静音/取消静音控件
在调用 loadAd 之前设置以上属性。对静态图片素材无效。对于 Reels 风格的信息流,将三个属性全部设置为 YES

构建原生广告布局

创建 CLXNativeAdView,使用视图绑定器将自定义子视图映射到素材角色:
- (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;
}
你也可以直接在 CLXNativeAdView 上设置 outlet:
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;

加载广告

流程 A — 加载到预构建的视图中:
CLXNativeAdView *adView = [self createNativeAdView];
[self.nativeAdLoader loadAdIntoAdView:adView];
流程 B — 先加载,稍后渲染(延迟渲染):
[self.nativeAdLoader loadAd];

- (void)didLoadNativeAd:(nullable CLXNativeAdView *)nativeAdView forAd:(CLXAd *)ad {
    CLXNativeAdView *adView = /* 创建广告视图 */;
    [self.nativeAdLoader renderNativeAdView:adView withAd:ad];
    [self.view addSubview:adView];
}

处理回调

#pragma mark - CLXNativeAdDelegate(必选)

- (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(可选)

- (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);
}

清理资源

使用完毕后务必销毁广告:
// 销毁特定已加载的广告
[self.nativeAdLoader destroyAd:ad];

// 销毁加载器及所有关联资源
[self.nativeAdLoader destroy];

原生广告素材(CLXNativeAd)

CLXNativeAd 对象可通过代理回调中的 ad.nativeAd 获取:
属性类型说明
titleNSString?标题文本
bodyNSString?正文/描述文本
callToActionNSString?CTA 按钮文本(如 “Install Now”)
advertiserNSString?广告主名称
iconCLXNativeAdImage?应用图标图片
mainImageCLXNativeAdImage?主图片(静态素材)
mediaViewUIView?视频/媒体播放器视图(由适配器提供)
optionsViewUIView?AdChoices 或选项视图(由适配器提供)
mediaContentAspectRatioCGFloat媒体内容宽高比
starRatingNSNumber?应用商店评分(0–5)
isVideoContentBOOL素材是否为视频
videoDurationNSTimeInterval视频时长(秒),未知时为 0
expiredBOOL广告是否已过期

Reels 信息流使用提示

  • 使用 UICollectionView,设置 pagingEnabled = YES 并配合垂直方向的 UICollectionViewFlowLayout,设置 minimumLineSpacing = 0,每个单元格全屏显示。
  • 在回收单元格时调用 CLXNativeAdViewprepareForReuse
  • 每个广告位创建一个 CLXNativeAdLoader,按顺序加载广告。
  • 不再需要广告时通过 destroyAd: 销毁。