AdVista SDKAdVista SDK
  • 指南

    • Advista 广告SDK隐私政策
    • Advista 广告SDK合规使用说明
    • Advista 广告SDK应用权限申请与使用情况说明
    • Advista 流量变现平台用户服务协议
    • Android 集成手册
    • iOS 集成手册
      • iOS SDK 版本更新记录
      • 目录
      • SDK 接入准备及初始化文档
      • 开屏广告
      • 插屏广告
      • 原生广告
      • 激励视频
      • 错误码说明
    • Report API 文档

iOS 集成手册

iOS SDK 版本更新记录

版本号更新日期更新内容
1.1.02025-01-12iOS 初始版本发布

目录

  • SDK 接入准备及初始化文档
  • 开屏广告
  • 插屏广告
  • 原生广告
  • 激励视频
  • 错误码说明

SDK 接入准备及初始化文档

SDK接入准备

  1. 在Advista平台注册账号后,创建应用、代码位。 a. 开发联调阶段建议创建测试应用/代码位,测试代码位几乎满填,方便验证广告加载和展示效果。
  2. 下载 SDK 并集成到应用内。集成完毕后,首先需要先初始化SDK,并填写平台创建的AppID(应用ID)。然后根据您的需求接入不同的广告功能,按照规范调用各个广告类型方法。
  3. 每一次广告加载时都需要填写sposId(代码位ID)。

SDK 集成

系统要求

  • iOS 13.0 及以上版本
  • Xcode 12.0 及以上版本

CocoaPods 集成

  1. 在 Podfile 中添加源:
source 'https://cdn.cocoapods.org/'
  1. 在 Podfile 中添加依赖,并执行 pod install:
pod 'advista', '~> 1.1.0'
pod 'OpenSSL-Universal', '~> 1.1'
  1. 执行安装:
pod install

手动集成

  1. 下载 SDK 文件

    • 从 Advista 平台下载最新版本的 SDK Framework
    • 支持 .framework
  2. 集成 Framework

    • 将 advista.framework 拖拽到 Xcode 项目中
    • 在项目设置中,确保 Framework 已添加到 "Embedded Binaries" 和 "Linked Frameworks and Libraries"
  3. 添加系统依赖

    • 在项目设置中,确保已链接以下系统框架:
      • UIKit.framework
      • Foundation.framework
      • AVFoundation.framework(用于视频广告)
      • WebKit.framework(用于广告展示)
      • CoreMotion.framework(用于摇一摇功能)
  4. 配置 Info.plist

    • 添加网络权限(如果需要):
      <key>NSAppTransportSecurity</key>
      <dict>
          <key>NSAllowsArbitraryLoads</key>
          <false/>
      </dict>
    • 添加定位权限(如果使用定位功能):
      <key>NSLocationWhenInUseUsageDescription</key>
      <string>用于提供更精准的广告推荐</string>
  5. 导入头文件

    #import <advista/advista.h>
    // 或者
    #import "advista/advista.h"

SDK 初始化示例

#import "ViewController.h"
#import "advista/advista.h"
#import "UIView+Toast.h"

@interface ViewController () <AdvistaInitListener>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    AdvistaSDKConfig *config = [[AdvistaSDKConfig alloc]init];
    config.appId = @"000000";
    config.bundleId = @"bundleId";  // 可选,不设置会自动获取
    config.debugMode = NO;  // 生产环境必须设置为 NO
    
    [[AdvistaSDK sharedInstance]setupWithConf:config listener:self];
}

- (void)onInitFailed:(NSInteger)code errorMsg:(nonnull NSString *)errorMsg {
    [self.view makeToast:errorMsg];
}

- (void)onInitSuccess {
    [self.view makeToast:@"初始化成功"];
}


@end

AdvistaSDKConfig 配置说明

属性类型含义是否必选默认值
appIdNSString应用ID,从 Advista 平台获取必选-
bundleIdNSString应用的 Bundle Identifier可选自动获取
debugModeBOOL开发阶段控制台日志开关,开启后输出详细日志,上线前必须设置为 NO可选NO
locationBOOL是否开启定位,当 app 获取到定位授权后,SDK 会读取定位信息;设置为 NO 后,SDK 不会再获取定位信息可选YES
carrierBOOL是否允许 SDK 获取运营商信息;设置为 NO 后,SDK 不会再获取运营商信息可选YES
enablePersonalizedBOOL个性化推荐开关;设置为 NO 后,SDK 将不再根据个性化能力推荐广告可选YES
IDFVBOOL是否允许 SDK 获取 IDFV;设置为 NO 后,SDK 不会再获取 IDFV 信息可选YES
IDFABOOL是否收集 IDFA,当 app 获取到 IDFA 授权后,SDK 会读取 IDFA 信息;设置为 NO 后,SDK 不会再获取 IDFA 信息可选YES
customIDFANSString自定义 IDFA,开发者可自行获取传入。传入非空的字符串后,SDK 将不再主动获取。注意:要传入正确的 IDFA,不要随意填写内容可选nil
customIDFVNSString自定义 IDFV,开发者可以自行获取 IDFV 传入可选nil
customCarrierNSString自定义运营商信息,开发者可以自行获取运营商信息传入,格式为 mcc 拼接 mnc,如 46000可选nil
customLocationNSString自定义位置信息,开发者可以自行获取传入可选nil

注意事项:

  • appId 是必填项,必须从 Advista 平台获取
  • bundleId 如果不设置,SDK 会自动从 [NSBundle mainBundle] bundleIdentifier] 获取
  • 生产环境必须将 debugMode 设置为 NO,避免泄露敏感信息
  • 自定义设备信息(customIDFA、customIDFV 等)一旦设置,SDK 将使用自定义值,不再主动获取

开屏广告

概述

开屏广告是应用程序启动时呈现的全屏广告,开发者只需遵循标准接入流程即可展示广告视图。开屏广告在应用启动时显示,持续5秒后自动关闭。用户也可以点击“跳过”快速进入主界面,或点击广告了解更多信息。

广告加载参数AdLoadParams.Builder方法说明

方法说明是否必填
setSposId:(NSString *)sposId设置代码位id,sposId不能为空必填
setLoadTimeOut:(NSInteger)loadTimeOut加载超时时间,默认5s(单位:毫秒)可选
setMute:(BOOL)isMute设置视频素材是否默认静音可选
setShake:(BOOL)isShake是否允许摇一摇广告,默认YES可选

AdvistaTemplateAd方法说明

方法/属性含义
isReady对于已经加载成功,但未及时展示的广告,在展示前用此方法判断广告是否还可用
showAdInWindow用于调用已经加载成功的广告的展示
getECPM获取当前广告的价格 单位 分(人民币)

AdvistaSplashAd的代理方法

@protocol AdvistaAdDelegate <NSObject>
@required
/// 广告加载成功
- (void)onAdLoaded:(AdvistaTemplateAd *)ad;
/// 广告的加载的各种错误信息
- (void)onAdFailedToLoad:(NSInteger)code errorMsg:(NSString *)errorMsg;
/// 广告展示的错误信息
- (void)onShowError:(NSInteger)code errorMsg:(NSString *)errorMsg;
/// 点击了广告
- (void)onAdClicked;
/// 关闭了广告
- (void)onAdClosed;
/// 广告曝光了
- (void)onAdExposure;
/// 广告资源加载成功
- (void)onResourceReady;
@end

开屏广告的使用

#import "advista/advista.h"
#import "UIView+Toast.h"

@implementation SplashViewController

- (IBAction)loadAndShow:(UIButton *)sender {
    
    // 创建自定义底部视图
    AdLoadParamsBuilder* builder = [[AdLoadParamsBuilder alloc]init];
    [builder setSposId:@"111111"];
    [builder setShake:YES];
    CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
    //设置开屏底部bottomView 可选
    UIView *customBottomView;
    if (_bottomSwitch.on) {
        customBottomView = [[UIView alloc] init];
        customBottomView.backgroundColor = [UIColor blackColor];
        // 设置 bottomView 的高度
        customBottomView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 100);
        [builder setAdSize:CGSizeMake(screenWidth, 700)];
    }
    AdLoadParams *params = builder.build;
    [[AdvistaSDK sharedInstance]loadSplashAdWithParams:params customBottomView:customBottomView listener:self];
    
}
- (void)onAdClicked { 
    [self.view makeToast:@"广告被点击了"];
}

- (void)onAdClosed { 
    [self.view makeToast:@"广告被关闭了"];
}

- (void)onAdExposure { 
    [self.view makeToast:@"广告曝光了"];
}

- (void)onAdFailedToLoad:(NSInteger)code errorMsg:(nonnull NSString *)errorMsg { 
    [self.view makeToast:@"广告加载失败"];
}

- (void)onAdLoaded:(nonnull AdvistaTemplateAd *)ad { 
    [self.view makeToast:@"广告加载成功"];
    _splashAd = ad;
    [self showAd];
}

- (void)onResourceReady { 
    [self.view makeToast:@"广告isReady"];
    [self showAd];
}

- (void)showAd{
    if (_splashAd && _splashAd.isReady) {
        [_splashAd showAdInWindow:self.view.window];
    }
}

- (void)onShowError:(NSInteger)code errorMsg:(nonnull NSString *)errorMsg { 
    
}

@end

插屏广告

概述

插屏广告是移动广告的一种常见形式,一般在应用使用过程中弹出,用户可以选择点击广告以访问目标网址,或者关闭广告以返回应用。 插屏广告有两种形式:半屏和全屏。两者都覆盖整个屏幕,区别在于广告内容的展示区域大小。半屏广告在展示区域之外,背景为半透明。

广告加载参数AdLoadParams.Builder方法说明

方法说明是否必填
setSposId:(NSString *)sposId设置代码位id,sposId不能为空必填
setLoadTimeOut:(NSInteger)loadTimeOut加载超时时间,默认5s(单位:毫秒)可选
setMute:(BOOL)isMute设置视频素材是否默认静音可选
setShake:(BOOL)isShake是否允许摇一摇广告,默认YES可选

AdvistaTemplateAd方法说明

方法/属性含义
isReady对于已经加载成功,但未及时展示的广告,在展示前用此方法判断广告是否还可用
showAdInWindow用于调用已经加载成功的广告的展示
getECPM获取当前广告的价格 单位 分(人民币)

AdvistaSplashAd的代理方法

@protocol AdvistaAdDelegate <NSObject>
@required
/// 广告加载成功
- (void)onAdLoaded:(AdvistaTemplateAd *)ad;
/// 广告的加载的各种错误信息
- (void)onAdFailedToLoad:(NSInteger)code errorMsg:(NSString *)errorMsg;
/// 广告展示的错误信息
- (void)onShowError:(NSInteger)code errorMsg:(NSString *)errorMsg;
/// 点击了广告
- (void)onAdClicked;
/// 关闭了广告
- (void)onAdClosed;
/// 广告曝光了
- (void)onAdExposure;
/// 广告资源加载成功
- (void)onResourceReady;
@end

插屏广告的使用

#import "PopupViewController.h"
#import "UIView+Toast.h"


@implementation PopupViewController 

- (IBAction)loadAndShow:(id)sender {
    AdLoadParamsBuilder *builder = [[AdLoadParamsBuilder alloc]init];
    [builder setSposId:@"30272174"];
    [builder setLoadTimeOut:5000];
    [builder setShake:YES];
    AdLoadParams *params = [builder build];
    [[AdvistaSDK sharedInstance] loadInterstitialWithParams:params listener:self];
}
- (void)onAdClicked { 
    [self.view makeToast:@"广告被点击了"];
}

- (void)onAdClosed { 
    [self.view makeToast:@"广告被关闭了"];
}

- (void)onAdExposure { 
    [self.view makeToast:@"广告曝光了"];
}

- (void)onAdFailedToLoad:(NSInteger)code errorMsg:(nonnull NSString *)errorMsg { 
    [self.view makeToast:@"广告加载失败"];
}

- (void)onAdLoaded:(nonnull AdvistaTemplateAd *)ad { 
    if (ad) {
        _interstitialAd = ad;
        [self.view makeToast:@"广告加载成功"];
    }
}

- (void)onResourceReady { 
    if (_interstitialAd && _interstitialAd.isReady) {
        [_interstitialAd showAdInWindow:self.view.window];
    }
}

- (void)onShowError:(NSInteger)code errorMsg:(nonnull NSString *)errorMsg { 
    
}


@end

原生广告

概述

原生广告是一种与应用内容和设计自然融合的广告形式,开发者只需按照标准集成步骤即可在应用中无缝展示广告内容。原生广告能够与应用的界面和用户体验协调一致,不会干扰用户的正常使用。用户可以在浏览应用内容时自然地接触到这些广告,从而提高广告的接受度和互动性。开发者可以根据应用的风格和用户的需求定制广告的展示方式,以实现最佳的广告效果和用户体验。

原生广告模版渲染和开发者自渲染

模板渲染广告:

广告加载参数AdLoadParams.Builder方法说明

方法说明是否必填
setSposId:(NSString *)sposId设置代码位id,sposId不能为空必填
setLoadTimeOut:(NSInteger)loadTimeOut加载超时时间,默认5s(单位:毫秒)可选
setMute:(BOOL)isMute设置视频素材是否默认静音可选
setShake:(BOOL)isShake是否允许摇一摇广告,默认YES可选
setAdSize:(CGSize)adSize原生广告加载的尺寸,width必传,高度可选可选
setSizeToFit:(BOOL)sizeToFit原生广告是否自适应尺寸可选

AdvistaTemplateAd方法说明

方法/属性含义
isReady对于已经加载成功,但未及时展示的广告,在展示前用此方法判断广告是否还可用
getECPM获取当前广告的价格 单位 分(人民币)
getAdView获取当前原生广告的视图进行填充

模板渲染原生广告的使用

#import "FeedsViewController.h"
#import "UIView+Toast.h"

@implementation FeedsViewController

- (IBAction)loadAndShow:(id)sender {
    AdLoadParamsBuilder *builder = [[AdLoadParamsBuilder alloc]init];
    [builder setMute:YES];
    [builder setShake:YES];
    [builder setSposId:@"20300726"];
    [builder setSizeToFit:NO];
//    [builder setWidth:UIViewAutoresizingFlexibleWidth];
    CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
    CGFloat width = screenWidth;  // 添加这行
    [builder setAdSize:CGSizeMake(width, 0)];  // 添加这行
    [[AdvistaSDK sharedInstance] loadNativeAdWithParams:builder.build listener:self];
}
- (void)onAdClicked { 
    
}

- (void)onAdClosed { 
    
}

- (void)onAdExposure { 
    
}

- (void)onAdFailedToLoad:(NSInteger)code errorMsg:(nonnull NSString *)errorMsg { 
    
}

- (void)onAdLoaded:(nonnull AdvistaTemplateAd *)ad { 
    if (ad) {
        self.feedsAd = ad;
        [self.view makeToast:@"原生广告加载成功"];
    }
}

- (void)onResourceReady { 
    [self showAd];
}

- (void)onShowError:(NSInteger)code errorMsg:(nonnull NSString *)errorMsg { 
    
}

- (void)showAd {
    if (self.feedsAd && self.feedsAd.isReady) {
        // 先移除之前的广告视图
        for (UIView *subview in self.view.subviews) {
            if ([subview isKindOfClass:[AdvistaBaseAdView class]]) {
                [subview removeFromSuperview];
            }
        }
        AdvistaBaseAdView *adView = [_feedsAd getAdView];
        [self.view addSubview:adView];
    }
}


@end

开发者自渲染:

广告加载参数AdLoadParams.Builder方法说明

方法说明是否必填
setSposId:(NSString *)sposId设置代码位id,sposId不能为空必填
setLoadTimeOut:(NSInteger)loadTimeOut加载超时时间,默认5s(单位:毫秒)可选
setUserId:(NSString *)userId设置用户ID,用于激励视频奖励验证可选
setExtraInfo:(NSString *)extraInfo设置自定义信息,会传递给服务端可选

AdvistaSelfRenderAdListener代理方法

@protocol AdvistaSelfRenderAdListener <NSObject>
- (void)onSelfRenderAdLoaded:(AdvistaNativeFeedsData *)nativeFeedsData;
- (void)onSelfRenderAdLoadError:(NSInteger)code message:(NSString *)message;
- (void)onSelfRenderAdClosed;
- (void)onSelfRenderAdExposure;
- (void)onSelfRenderAdExposureFailed:(NSInteger)code message:(NSString *)message;
- (void)onSelfRenderAdClicked;
@end

自渲染素材类AdvistaNativeFeedsData

属性说明
getMaterialType0: 素材是图片内容 , 1: 素材是视频内容
getVideoUrl视频地址
getImageUrl图片地址
getIconUrl广告的logo
getAdsLogoBitmap广告角标
getDesc描述
getECPM价格
getTitle标题
getCtaText交互按钮文案
getLogoBitmap广告的logo地址
getMainImageWidth图片宽度
getMainImageHeight图片高度
getVideoPlayer广告视频播放的view

AdvistaNativeFeedsData方法介绍

方法说明
registerSelfRenderViews绑定广告数据对象,渲染广告视图前调用,注册可点击子视图数组,设置摇一摇尺寸

AdvistaNativeVideoViewDelegate方法

@protocol AdvistaNativeVideoViewDelegate <NSObject>

- (void)onVideoLoading;//视频加载
- (void)onVideoReady;//视频ready
- (void)onVideoStart;//视频开始
- (void)onVideoProgress:(double)progress;//视频进度
- (void)onVideoPause;//视频暂停
- (void)onVideoResume;//视频恢复
- (void)onVideoCompleted;//视频结束
- (void)onVideoStop;//视频停止
- (void)onVideoError:(NSInteger)errorType;//视频错误

接入示例

#import "SelfRenderViewController.h"
#import "AdvistaSdk.h"
#import "AdvistaSelfRenderAd.h"
#import "AdvistaNativeVideoPlayerView.h"
#import "UIView+Toast.h"
#import "Constant.h"

@interface SelfRenderViewController() <AdvistaSelfRenderAdListener>

@end

@implementation SelfRenderViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupUI];
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    tapGesture.cancelsTouchesInView = NO;
    [self.view addGestureRecognizer:tapGesture];
    self.selfRenderText.text = ADVISTA_SELF_RENDER_ID;
}

- (void)setupUI {
    // 创建广告容器视图
    self.adContainerView = [[UIView alloc] init];
    self.adContainerView.backgroundColor = [UIColor whiteColor];
    self.adContainerView.layer.cornerRadius = 8;
    self.adContainerView.layer.shadowColor = [UIColor blackColor].CGColor;
    self.adContainerView.layer.shadowOffset = CGSizeMake(0, 2);
    self.adContainerView.layer.shadowOpacity = 0.1;
    self.adContainerView.layer.shadowRadius = 4;
    self.adContainerView.hidden = YES;
    [self.view addSubview:self.adContainerView];
    
    // 创建广告图片视图
    self.adImageView = [[UIImageView alloc] init];
    self.adImageView.contentMode = UIViewContentModeScaleAspectFill;
    self.adImageView.clipsToBounds = YES;
    self.adImageView.layer.cornerRadius = 4;
    [self.adContainerView addSubview:self.adImageView];
    
    // 创建标题标签
    self.titleLabel = [[UILabel alloc] init];
    self.titleLabel.font = [UIFont boldSystemFontOfSize:16];
    self.titleLabel.textColor = [UIColor blackColor];
    self.titleLabel.numberOfLines = 2;
    [self.adContainerView addSubview:self.titleLabel];
    
    // 创建副标题标签
    self.subTitleLabel = [[UILabel alloc] init];
    self.subTitleLabel.font = [UIFont systemFontOfSize:14];
    self.subTitleLabel.textColor = [UIColor grayColor];
    self.subTitleLabel.numberOfLines = 1;
    [self.adContainerView addSubview:self.subTitleLabel];
    
    // 创建更多按钮
    self.moreButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.moreButton setTitle:@"了解更多" forState:UIControlStateNormal];
    [self.moreButton setTitleColor:[UIColor systemBlueColor] forState:UIControlStateNormal];
    self.moreButton.titleLabel.font = [UIFont systemFontOfSize:12];
    self.moreButton.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.0];
    self.moreButton.layer.cornerRadius = 4;
    self.moreButton.contentEdgeInsets = UIEdgeInsetsMake(4, 8, 4, 8);
    [self.adContainerView addSubview:self.moreButton];
    
    // 创建关闭按钮
    self.closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.closeButton setTitle:@"×" forState:UIControlStateNormal];
    [self.closeButton setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
    self.closeButton.titleLabel.font = [UIFont boldSystemFontOfSize:18];
    // 添加点击事件
    [self.closeButton addTarget:self action:@selector(onCloseButtonTapped) forControlEvents:UIControlEventTouchUpInside];
    [self.adContainerView addSubview:self.closeButton];
    
    // 创建广告角标
    self.adsLogoView = [[UIImageView alloc] init];
    self.adsLogoView.contentMode = UIViewContentModeScaleAspectFit;
    [self.adContainerView addSubview:self.adsLogoView];
    

    // 创建视频状态标签
    self.videoStatusLabel = [[UILabel alloc] init];
    self.videoStatusLabel.font = [UIFont systemFontOfSize:12];
    self.videoStatusLabel.textColor = [UIColor whiteColor];
    self.videoStatusLabel.textAlignment = NSTextAlignmentCenter;
    self.videoStatusLabel.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
    self.videoStatusLabel.layer.cornerRadius = 4;
    self.videoStatusLabel.clipsToBounds = YES;
    self.videoStatusLabel.text = @"视频加载中...";
    self.videoStatusLabel.hidden = YES;
    [self.adContainerView addSubview:self.videoStatusLabel];

    // 创建视频进度条
    self.videoProgressView = [[UIProgressView alloc] init];
    self.videoProgressView.progressTintColor = [UIColor systemBlueColor];
    self.videoProgressView.trackTintColor = [UIColor lightGrayColor];
    self.videoProgressView.hidden = YES;
    [self.adContainerView addSubview:self.videoProgressView];

    // 创建播放/暂停按钮
    self.playPauseButton = [UIButton buttonWithType:UIButtonTypeSystem];
    [self.playPauseButton setTitle:@"播放" forState:UIControlStateNormal];
    [self.playPauseButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    self.playPauseButton.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
    self.playPauseButton.layer.cornerRadius = 4;
    self.playPauseButton.hidden = YES;
    [self.playPauseButton addTarget:self action:@selector(onPlayPauseTapped) forControlEvents:UIControlEventTouchUpInside];
    [self.adContainerView addSubview:self.playPauseButton];

    // 创建静音按钮
    self.muteButton = [UIButton buttonWithType:UIButtonTypeSystem];
    [self.muteButton setTitle:@"静音" forState:UIControlStateNormal];
    [self.muteButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    self.muteButton.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
    self.muteButton.layer.cornerRadius = 4;
    self.muteButton.hidden = YES;
    [self.muteButton addTarget:self action:@selector(onMuteTapped) forControlEvents:UIControlEventTouchUpInside];
    [self.adContainerView addSubview:self.muteButton];
    
    // 设置约束
    [self setupConstraints];
}

- (void)setupConstraints {
    // 设置广告容器约束
    self.adContainerView.translatesAutoresizingMaskIntoConstraints = NO;
    [NSLayoutConstraint activateConstraints:@[
        [self.adContainerView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
        [self.adContainerView.topAnchor constraintEqualToAnchor:self.view.topAnchor],
        [self.adContainerView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:10],
        [self.adContainerView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-10],
        [self.adContainerView.heightAnchor constraintEqualToConstant:100]
    ]];
    
    // 设置广告图片约束 - 左侧
    self.adImageView.translatesAutoresizingMaskIntoConstraints = NO;
    [NSLayoutConstraint activateConstraints:@[
        [self.adImageView.leadingAnchor constraintEqualToAnchor:self.adContainerView.leadingAnchor constant:12],
        [self.adImageView.topAnchor constraintEqualToAnchor:self.adContainerView.topAnchor constant:12],
        [self.adImageView.bottomAnchor constraintEqualToAnchor:self.adContainerView.bottomAnchor constant:-12],
        [self.adImageView.widthAnchor constraintEqualToConstant:132],
        [self.adImageView.heightAnchor constraintEqualToConstant:74]
    ]];
    
    // 设置标题约束 - 右侧
    self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
    [NSLayoutConstraint activateConstraints:@[
        [self.titleLabel.leadingAnchor constraintEqualToAnchor:self.adImageView.trailingAnchor constant:12],
        [self.titleLabel.topAnchor constraintEqualToAnchor:self.adImageView.topAnchor],
        [self.titleLabel.trailingAnchor constraintEqualToAnchor:self.adContainerView.trailingAnchor constant:-12]
    ]];
    
    // 设置更多按钮约束 - 底部
    self.moreButton.translatesAutoresizingMaskIntoConstraints = NO;
    [NSLayoutConstraint activateConstraints:@[
        [self.moreButton.trailingAnchor constraintEqualToAnchor:self.adContainerView.trailingAnchor constant:-40],
        [self.moreButton.bottomAnchor constraintEqualToAnchor:self.adImageView.bottomAnchor],
        [self.moreButton.widthAnchor constraintEqualToConstant:68]
    ]];
    // 添加调试日志
    
    // 设置副标题约束 - 标题下方
    self.subTitleLabel.translatesAutoresizingMaskIntoConstraints = NO;
    [NSLayoutConstraint activateConstraints:@[
        [self.subTitleLabel.bottomAnchor constraintEqualToAnchor:self.adImageView.bottomAnchor],
        [self.subTitleLabel.leadingAnchor constraintEqualToAnchor:self.titleLabel.leadingAnchor],
        [self.subTitleLabel.trailingAnchor constraintEqualToAnchor:self.moreButton.leadingAnchor]
    ]];
    
    
    // 设置关闭按钮约束 - 右上角
    self.closeButton.translatesAutoresizingMaskIntoConstraints = NO;
    [NSLayoutConstraint activateConstraints:@[
        [self.closeButton.trailingAnchor constraintEqualToAnchor:self.adContainerView.trailingAnchor constant:-10],
        [self.closeButton.bottomAnchor constraintEqualToAnchor:self.adImageView.bottomAnchor]
    ]];
    
    // 设置广告角标约束
    self.adsLogoView.translatesAutoresizingMaskIntoConstraints = NO;
    [NSLayoutConstraint activateConstraints:@[
        [self.adsLogoView.leadingAnchor constraintEqualToAnchor:self.adImageView.leadingAnchor],
        [self.adsLogoView.bottomAnchor constraintEqualToAnchor:self.adImageView.bottomAnchor]
    ]];
    

    // 修改视频状态标签约束 - 不要覆盖整个广告图片区域
    self.videoStatusLabel.translatesAutoresizingMaskIntoConstraints = NO;
    [NSLayoutConstraint activateConstraints:@[
        [self.videoStatusLabel.leadingAnchor constraintEqualToAnchor:self.adImageView.leadingAnchor],
        [self.videoStatusLabel.trailingAnchor constraintEqualToAnchor:self.adImageView.trailingAnchor],
        [self.videoStatusLabel.topAnchor constraintEqualToAnchor:self.adImageView.topAnchor],
        [self.videoStatusLabel.heightAnchor constraintEqualToConstant:20] // 设置固定高度,不要覆盖整个区域
    ]];

    // 修改视频进度条约束 - 放在广告图片底部
    self.videoProgressView.translatesAutoresizingMaskIntoConstraints = NO;
    [NSLayoutConstraint activateConstraints:@[
        [self.videoProgressView.leadingAnchor constraintEqualToAnchor:self.adImageView.leadingAnchor],
        [self.videoProgressView.trailingAnchor constraintEqualToAnchor:self.adImageView.trailingAnchor],
        [self.videoProgressView.bottomAnchor constraintEqualToAnchor:self.adImageView.bottomAnchor constant:-5],
        [self.videoProgressView.heightAnchor constraintEqualToConstant:2]
    ]];

    // 修改播放/暂停按钮约束 - 放在广告图片中心,但不要与状态标签重叠
    self.playPauseButton.translatesAutoresizingMaskIntoConstraints = NO;
    [NSLayoutConstraint activateConstraints:@[
        [self.playPauseButton.centerXAnchor constraintEqualToAnchor:self.adImageView.centerXAnchor],
        [self.playPauseButton.centerYAnchor constraintEqualToAnchor:self.adImageView.centerYAnchor constant:10], // 向下偏移10点,避免与状态标签重叠
        [self.playPauseButton.widthAnchor constraintEqualToConstant:60],
        [self.playPauseButton.heightAnchor constraintEqualToConstant:30]
    ]];

    self.muteButton.translatesAutoresizingMaskIntoConstraints = NO;
    [NSLayoutConstraint activateConstraints:@[
        [self.muteButton.trailingAnchor constraintEqualToAnchor:self.adImageView.trailingAnchor constant:-5],
        [self.muteButton.topAnchor constraintEqualToAnchor:self.adImageView.topAnchor constant:5],
        [self.muteButton.widthAnchor constraintEqualToConstant:40],
        [self.muteButton.heightAnchor constraintEqualToConstant:25]
    ]];
}

- (void)loadAd {
    self.isLoadAndShow = NO;
    AdLoadParamsBuilder* builder = [[AdLoadParamsBuilder alloc]init];
    [builder setSposId:self.selfRenderText.text];
    AdLoadParams *params = builder.build;
    [[AdvistaSDK sharedInstance] loadSelfRenderAdWithParams:params listener:self];
}

- (BOOL)isReady {
    if (self.nativeData) {
        return YES;
    }
    return NO;
}


- (void)showAd {
    if (self.nativeData) {
        [self renderAdWithNativeData:self.nativeData];
    }
}

- (void)loadAndShow {
    self.isLoadAndShow = YES;
    AdLoadParamsBuilder* builder = [[AdLoadParamsBuilder alloc]init];
    [builder setSposId:self.selfRenderText.text];
    AdLoadParams *params = builder.build;
    [[AdvistaSDK sharedInstance] loadSelfRenderAdWithParams:params listener:self];
}

- (void)renderAdWithNativeData:(AdvistaNativeFeedsData *)nativeData {
    self.adContainerView.hidden = NO;
    self.adContainerView.alpha = 1.0;
    
    self.titleLabel.text = [nativeData getTitle];
    self.subTitleLabel.text = [nativeData getDesc];
    
    UIImage *logoImage = [nativeData getAdsLogoBitmap];
    if (logoImage) {
        self.adsLogoView.image = logoImage;
    }
    
    // 根据素材类型设置内容
    if (nativeData.materialType == 1) {
        // 视频素材
        [self setupVideoContent:nativeData];
    } else {
        // 图片素材
        [self setupImageContent:nativeData];
    }
    
    // 注册自渲染视图
    [nativeData registerSelfRenderViews:self.adContainerView
                             clickViews:@[self.adContainerView, self.moreButton]
                             shakeWidth:100
                            shakeHeight:50];
}

- (void)setupVideoContent:(AdvistaNativeFeedsData *)nativeData {
    // 隐藏图片,显示视频
    self.adImageView.hidden = YES;
    
    // 显示视频控制UI
    self.videoStatusLabel.hidden = NO;
    self.videoProgressView.hidden = NO;
    self.playPauseButton.hidden = NO;
    self.muteButton.hidden = NO;
    
    // 获取视频播放器
    AdvistaNativeVideoPlayerView *videoPlayer = [nativeData getVideoPlayer];
    if (videoPlayer) {
        // 设置视频播放器的监听器
        videoPlayer.listener = self;
        [videoPlayer showInView:self.adContainerView withFrame:self.adImageView.frame];
    }
}

- (void)setupImageContent:(AdvistaNativeFeedsData *)nativeData {
    // 显示图片,隐藏视频
    self.adImageView.hidden = NO;
    
    // 加载广告图片
    NSString *imageUrl = [nativeData getImageUrl];
    if (imageUrl && imageUrl.length > 0) {
        [self loadImageFromURL:imageUrl];
    }
}

- (void)loadImageFromURL:(NSString *)urlString {
    NSURL *url = [NSURL URLWithString:urlString];
    if (url) {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSData *data = [NSData dataWithContentsOfURL:url];
            if (data) {
                UIImage *image = [UIImage imageWithData:data];
                dispatch_async(dispatch_get_main_queue(), ^{
                    self.adImageView.image = image;
                });
            }
        });
    }
}


- (void)onSelfRenderAdLoaded:(AdvistaNativeFeedsData *)nativeFeedsData{
    [self.view makeToast:@"加载成功" duration:1.0 position:[CSToastManager defaultPosition]];
    if (nativeFeedsData) {
        self.nativeData = nativeFeedsData;
        
        if (self.isLoadAndShow) {
            [self showAd];
        }
    }
}

- (void)onSelfRenderAdLoadError:(NSInteger)code message:(NSString *)message{
    [self.view makeToast:message];
}

- (void)onSelfRenderAdClosed {
    // 可以在这里添加额外的关闭处理逻辑
}

- (void)onSelfRenderAdExposure {
    // 可以在这里添加曝光成功的处理逻辑
}

- (void)onSelfRenderAdExposureFailed:(NSInteger)code message:(NSString *)message {
    // 可以在这里添加曝光失败的处理逻辑
    [self.view makeToast:[NSString stringWithFormat:@"广告曝光失败: %@", message] duration:1.0 position:[CSToastManager defaultPosition]];
}

- (void)onSelfRenderAdClicked {
    // 可以在这里添加点击处理逻辑
    [self.view makeToast:@"广告被点击了!" duration:1.0 position:[CSToastManager defaultPosition]];
}

// 在文件末尾添加关闭按钮的点击处理方法
- (void)onCloseButtonTapped {
    
    // 隐藏广告容器
    [self hideAd];
    
}

// 添加隐藏广告的方法
- (void)hideAd {
    
    // 隐藏广告容器
    [UIView animateWithDuration:0.3 animations:^{
        self.adContainerView.alpha = 0.0;
    } completion:^(BOOL finished) {
//        [self.adContainerView removeFromSuperview];
        self.adContainerView.hidden = YES;
    }];
    
    // 停止视频播放(如果有)
    if (self.nativeData && self.nativeData.videoPlayerView) {
        [self.nativeData.getVideoPlayer destroy];
    }
    
    // 清理资源
    [self cleanupAdResources];
}

// 添加清理广告资源的方法
- (void)cleanupAdResources {
    // 清理自渲染视图
    if(self.nativeData){
        [self.nativeData destroy];
    }
}

// 在文件最后添加

#pragma mark - AdvistaNativeVideoViewListener

- (void)onVideoLoading {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.videoStatusLabel.text = @"视频加载中...";
        self.videoStatusLabel.hidden = NO;
        self.playPauseButton.hidden = YES;
    });
}

- (void)onVideoReady {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.videoStatusLabel.text = @"视频准备就绪";
        self.videoStatusLabel.hidden = NO;
        self.playPauseButton.hidden = NO;
        [self.playPauseButton setTitle:@"播放" forState:UIControlStateNormal];
    });
}

- (void)onVideoStart {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.videoStatusLabel.hidden = YES;
        self.playPauseButton.hidden = NO;
        [self.playPauseButton setTitle:@"暂停" forState:UIControlStateNormal];
    });
}

- (void)onVideoProgress:(double)progress {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.videoProgressView.progress = progress;
    });
}

- (void)onVideoPause {
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.playPauseButton setTitle:@"播放" forState:UIControlStateNormal];
    });
}

- (void)onVideoResume {
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.playPauseButton setTitle:@"暂停" forState:UIControlStateNormal];
    });
}

- (void)onVideoCompleted {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.videoStatusLabel.text = @"视频播放完成";
        self.videoStatusLabel.hidden = NO;
        [self.playPauseButton setTitle:@"重播" forState:UIControlStateNormal];
    });
}

- (void)onVideoStop {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.videoStatusLabel.text = @"视频已停止";
        self.videoStatusLabel.hidden = NO;
        [self.playPauseButton setTitle:@"播放" forState:UIControlStateNormal];
    });
}

- (void)onVideoError:(NSInteger)errorType {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.videoStatusLabel.text = [NSString stringWithFormat:@"视频错误: %ld", (long)errorType];
        self.videoStatusLabel.hidden = NO;
        [self.playPauseButton setTitle:@"重试" forState:UIControlStateNormal];
    });
}

- (void)onPlayPauseTapped {
    AdvistaNativeVideoPlayerView *videoPlayer = [self.nativeData getVideoPlayer];
    if (videoPlayer) {
        if ([self.playPauseButton.titleLabel.text isEqualToString:@"播放"] ||
            [self.playPauseButton.titleLabel.text isEqualToString:@"重播"]) {
            [videoPlayer startVideo];
        } else if ([self.playPauseButton.titleLabel.text isEqualToString:@"暂停"]) {
            [videoPlayer pauseVideo];
        }
    }
}

- (void)onMuteTapped {
    AdvistaNativeVideoPlayerView *videoPlayer = [self.nativeData getVideoPlayer];
    if (videoPlayer) {
        BOOL isMuted = videoPlayer.isMuted;
        [videoPlayer setVideoMute:!isMuted];
        [self.muteButton setTitle:isMuted ? @"静音" : @"取消静音" forState:UIControlStateNormal];
    }
}

// 点击空白处时调用的方法
- (void)dismissKeyboard {
    [self.view endEditing:YES];
}

@end

激励视频

概述

激励视频广告是一种全屏视频形式,用户完整观看后可领取奖励。这种广告常见于游戏中,如复活、获取道具或额外通关奖励等场景,以及应用内的增值服务,例如单次体验付费功能。

广告加载参数AdLoadParams.Builder方法说明

方法说明是否必填
setSposId:(NSString *)sposId设置代码位id,sposId不能为空必填
setLoadTimeOut:(NSInteger)loadTimeOut加载超时时间,默认5s(单位:毫秒)可选
setMute:(BOOL)isMute设置视频素材是否默认静音可选
setShake:(BOOL)isShake是否允许摇一摇广告,默认YES可选
setUserId:(NSString *)userId设置用户ID,用于激励视频奖励验证可选
setExtraInfo:(NSString *)extraInfo设置自定义信息,会传递给服务端可选

AdvistaTemplateAd方法说明

方法/属性含义
isReady对于已经加载成功,但未及时展示的广告,在展示前用此方法判断广告是否还可用
showAdInWindow用于调用已经加载成功的广告的展示
getECPM获取当前广告的价格 单位 分(人民币)

AdvistaRewardVideoAd的代理方法:

@protocol AdvistaAdDelegate <NSObject>
@required
/// 广告加载成功
- (void)onAdLoaded:(AdvistaTemplateAd *)ad;
/// 广告的加载的各种错误信息
- (void)onAdFailedToLoad:(NSInteger)code errorMsg:(NSString *)errorMsg;
/// 广告展示的错误信息
- (void)onShowError:(NSInteger)code errorMsg:(NSString *)errorMsg;
/// 点击了广告
- (void)onAdClicked;
/// 关闭了广告
- (void)onAdClosed;
/// 广告曝光了
- (void)onAdExposure;
/// 广告资源加载成功
- (void)onResourceReady;
@optional
/// 激励视频奖励验证结果
- (void)onRewardVerify:(AdvistaRewardInfo *)rewardInfo;
@end

AdvistaRewardInfo属性介绍

属性含义
rewardValid服务端校验结果
userId用户ID
transIdtransid
rewardAmount奖励数量
rewardName奖励名称
errCode错误码
errMsg错误信息
extraInfo自定义信息

激励视频广告的使用

#import "RewardVideoViewController.h"
#import "AdvistaSdk.h"
#import "AdvistaTemplateAd.h"
#import "UIView+Toast.h"
#import "Constant.h"

@interface RewardVideoViewController ()

@end

@implementation RewardVideoViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.rewardTxt.returnKeyType = UIReturnKeyDone;
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    tapGesture.cancelsTouchesInView = NO;
    [self.view addGestureRecognizer:tapGesture];
    self.rewardTxt.text = ADVISTA_REWARD_ID;
}


- (void)checkReady{
    if (self.rewardVideoAd) {
        if (self.rewardVideoAd.isReady) {
            [self.view makeToast:@"广告准备就绪" duration:1.0 position:[CSToastManager defaultPosition]];
        } else {
            [self.view makeToast:@"广告未准备就绪" duration:1.0 position:[CSToastManager defaultPosition]];
        }
    }
}

- (void)checkReady:(id)sender {
    [self checkReady];
}

- (void)loadAd{
    _loadShow = NO;
    AdLoadParamsBuilder *builder = [[AdLoadParamsBuilder alloc]init];
    [builder setMute:YES];
    [builder setShake:_shakeSwitch.on];
    [builder setSposId:self.rewardTxt.text];
    [[AdvistaSDK sharedInstance] loadRewardVideoWithParams:builder.build listener:self];
}

- (void)showAd{
    if (self.rewardVideoAd && self.rewardVideoAd.isReady) {
        // 先移除之前的广告视图
        [self.rewardVideoAd showAdInWindow:self.view.window];
    }
}

- (void)showAd:(id)sender {
    [self showAd];
}

- (void)loadAndShow{
    _loadShow = YES;
    AdLoadParamsBuilder *builder = [[AdLoadParamsBuilder alloc]init];
    [builder setMute:YES];
    [builder setShake:_shakeSwitch.on];
    [builder setSposId:self.rewardTxt.text];
    [[AdvistaSDK sharedInstance] loadRewardVideoWithParams:builder.build listener:self];
}

- (void)loadAndShow:(id)sender {
    [self loadAndShow];
}

- (void)onAdClicked {
    [self.view makeToast:@"广告点击" duration:1.0 position:[CSToastManager defaultPosition]];
}

- (void)onAdClosed { 
    [self.view makeToast:@"广告关闭" duration:1.0 position:[CSToastManager defaultPosition]];
}

- (void)onAdExposure { 
    [self.view makeToast:@"广告曝光" duration:1.0 position:[CSToastManager defaultPosition]];
}

- (void)onAdFailedToLoad:(NSInteger)code errorMsg:(nonnull NSString *)errorMsg { 
    [self.view makeToast:@"广告加载失败" duration:1.0 position:[CSToastManager defaultPosition]];
}

- (void)onAdLoaded:(nonnull AdvistaTemplateAd *)ad { 
    [self.view makeToast:@"广告加载成功" duration:1.0 position:[CSToastManager defaultPosition]];
    self.rewardVideoAd = ad;
}

- (void)onResourceReady { 
    [self.view makeToast:@"广告isReady" duration:1.0 position:[CSToastManager defaultPosition]];
    if (_loadShow) {
        [self showAd];
    }
}

- (void)onShowError:(NSInteger)code errorMsg:(nonnull NSString *)errorMsg { 
    
}

- (void)onRewardVerify:(AdvistaRewardInfo *)rewardInfo{
    if (rewardInfo.rewardValid) {
        // 奖励验证成功,发放奖励
        NSLog(@"奖励验证成功: %@, 数量: %@", rewardInfo.rewardName, rewardInfo.rewardAmount);
    } else {
        // 奖励验证失败
        NSLog(@"奖励验证失败: %@", rewardInfo.errMsg);
    }
}

@end

错误码说明

SDK 在回调中会返回错误码和错误信息,常见的错误码如下:

SDK 初始化相关错误码

错误码说明
10001初始化失败
10002SDK 已经初始化
10003SDK 未初始化

广告加载相关错误码

错误码说明
60001无广告填充
60002应用ID或代码位ID不存在
60003代码位ID为空
60004应用或代码位ID不合法
60005代码位ID不合法
60006应用或代码位ID不匹配
60007代码位类型不匹配
60008代码位请求尺寸不能为空
60009加载超时
60010其他异常,请联系技术人员
60011AdListener对象为空

广告展示相关错误码

错误码说明
70001viewGroup为空
70002广告超时
70003请将原生广告添加到viewGroup中
70004原生广告容器太小,无法展示
70005广告已被销毁
70006广告已展示
70007广告渲染类型不匹配
70008请将激励视频广告添加到window中
70009Window已销毁
70010广告已过期,无法展示
上次更新:
贡献者: yinpp
Prev
Android 集成手册
Next
Report API 文档