自渲染信息流

适用于 IFLYADLib 6.5.1。接入概览。完整方法签名以所安装版本的公开头为准。

先阅读配置与隐私。下面的代码为业务控制器片段:属性放在类声明内,方法放在 @implementation 内;requestConfig 是该指南中的宿主辅助方法。

NativeFeed 的文字与图片由媒体渲染,SDK 管理曝光、广告点击、跳转和视频播放。nativeFeedAdDidLoad: 后按 ad.adData.materialType 选择单图、多图或视频布局;图片由媒体下载,视频向 SDK 提供普通 UIView 作为承载视图。多图至少显示返回的前两张,第三张可能不存在。显示广告来源标识,并按 ctaText 和 interactionType 设置操作按钮。

下面是素材已经渲染、视图已经加入 adContainer 并完成布局后的挂载片段。nativeAd 由控制器强持有;mediaView 是显示图片的视图或视频承载视图,其他视图均已创建。完整加载、图片下载和布局代码见基础卡片示例。

#import <IFLYAdCore/IFLYAdCore.h>
#import <IFLYAdNativeFeed/IFLYNativeFeedAd.h>

@interface NativeFeedViewController () <IFLYNativeFeedAdDelegate>
@property (nonatomic, strong) IFLYNativeFeedAd *nativeAd;
@property (nonatomic, strong) UIView *adContainer;
@property (nonatomic, strong) UIView *mediaView;
@property (nonatomic, strong) UILabel *adTitleLabel;
@property (nonatomic, strong) UILabel *adBadgeLabel;
@property (nonatomic, strong) UIButton *ctaButton;
@property (nonatomic, strong) UIButton *closeButton;
@end

- (void)attachRenderedNativeAd {
    IFLYNativeFeedAd *ad = self.nativeAd;
    IFLYNativeFeedAdData *data = ad.adData;
    if (!data.isMaterialComplete) return;
    BOOL clickable = data.interactionType == IFLYNativeFeedAdInteractionTypeRedirect ||
                     data.interactionType == IFLYNativeFeedAdInteractionTypeDownload;
    self.ctaButton.hidden = !clickable;

    IFLYNativeFeedAdViewBinder *binder = [[IFLYNativeFeedAdViewBinder alloc] init];
    binder.containerView = self.adContainer;
    binder.renderViews = @[self.mediaView, self.adTitleLabel, self.adBadgeLabel];
    binder.clickViews = clickable ? @[self.ctaButton] : @[];
    binder.closeView = self.closeButton;
    binder.videoView = data.materialType == IFLYNativeFeedAdMaterialTypeVideo
        ? self.mediaView : nil;

    IFLYAdError *error = nil;
    if (![ad attachWithViewBinder:binder error:&error]) {
        NSLog(@"NativeFeed attach failed: %ld %@", (long)error.errorCode, error.errorDescription);
    }
}

- (void)leaveScreen {
    [IFLYNativeFeedAd detachAdFromContainerView:self.adContainer];
}

接入规则:

  • attachWithViewBinder:error: 必须在主线程同步调用;containerView 必填,视频素材必须提供普通 UIView 作为 videoView。
  • interactionType 为 Exposure 或 Unknown 时,clickViews 传 @[];为 Redirect 或 Download 时只传实际点击视图。
  • 如确实需要把 CTA 放在广告容器外,显式设置 binder.allowsExternalClickViews = YES,并保证 CTA 与广告处于同一 window/scene、可见且可交互。常规接入优先把 CTA 放在容器内部。
  • renderViews、closeView 和 videoView 始终需要位于 containerView 内。外部 CTA 点击时应位于当前广告所在 window/scene,尺寸有效、可见可交互,广告容器处于前台且至少 2/3 可见;不能把 window 或控制器根视图作为 CTA。
  • 外部 CTA 不满足点击条件时,delegate 通过 nativeFeedAd:didRejectClickWithError: 返回 IFLYAdErrorCodeNativeFeedClickViewsInvalid(71503)。按 [71503/<point>] 提示修正视图状态,不要自己补发曝光、点击或跳转。同一个点击视图不要同时交给多条广告。
  • 关闭按钮交给 closeView,不要同时给它添加广告点击回调;业务交互按钮应保留自己的事件处理,不要为了让广告响应而关闭业务交互。
  • Cell 离屏、复用或切换为普通内容时,必须对具体容器调用 detachAdFromContainerView:;不要用旧 indexPath 反查广告。
  • 固定、非复用且不迁移的单容器,可以同步调用 detachFromCurrentContainer;可复用列表必须按对应容器调用 detachAdFromContainerView:,不能把解绑异步延迟到下一轮。
  • 列表数据层持有 IFLYNativeFeedAd,Cell 只负责渲染和 attach/detach。条目暂时离屏可继续持有同一 Ad;永久删除或页面退出时 detach、置空 delegate 并释放 Ad。
  • SDK 管理视频播放器。绑定且曝光后可使用 startPlay、pausePlay、resumePlay、stopPlay 控制播放。

常用 adData 字段:materialType、templateId、title、desc、content、ctaText、brand、appName、icon、mainImage、imageList、imageURLs、videoURL、videoCoverURL、videoDuration、targetURL、deeplinkURL、marketURL、downloadURL、packageName、interactionType 和 interactType。点击和跳转由 SDK 处理,媒体不要自行打开这些 URL。

NativeFeed 回调包括 nativeFeedAdDidLoad:、nativeFeedAdDidRender:、nativeFeedAdDidExpose:、nativeFeedAdDidClick:、nativeFeedAd:didJumpWithSuccess:、nativeFeedAdDidClose:、nativeFeedAd:didFailWithError: 和 nativeFeedAd:didFailToRenderWithError:;视频素材还会触发播放状态回调。didRender 表示挂载完成,曝光仍需满足实际可见条件;不要把它作为曝光或点击的替代信号。

通用版不提供媒体摇一摇上报能力;reportMediaShakeTriggeredWithError: 在此发行包返回 IFLYAdErrorCodeNativeFeedMediaShakeUnavailable(71512),不要直接复用定制渠道的调用方式。

加载失败、重试与对象清理见失败处理与生命周期。