广告加载与展示
本文面向已完成安装的宿主,接口以所安装版本的 framework 公开头为准。先完成宿主隐私流程,再按广告形式创建、强持有对象并设置 delegate。
展示窗口与 Scene
展示、落地页、外跳回流、曝光判断和 UI 生命周期归属广告的实际来源 window/Scene。没有来源时,仅在前台应用 Scene 唯一且明确时兜底,不跨 Scene 随机选择;独立落地页始终属于来源 Scene。
开屏的 rootVC 必须已经入窗。在 Scene 宿主中使用 customWindow 时,窗口必须可见、尺寸有限且为正、已经关联 Scene,并与 rootVC.window 属于同一 Scene;它可以不是 key window,可以使用较高 windowLevel,也可以不设置 rootVC。输入无效时展示失败,修正窗口后可重试。
加载与展示
宿主还需为启动页设置自己的等待期限;请求超时不等于整个启动流程的等待期限。若 Ready 到达时页面不可见,示例在 viewDidAppear: 再检查;App 重新激活时也应在来源页面调用 tryShowSplash。再次检查前,宿主须确认来源 Scene 在前台、页面仍允许展示且没有冲突的模态界面。若已经进入主页面或超过宿主等待期限,调用 clearSplash 并继续业务,忽略旧实例回调;不要一直停留在启动页。
didFailWithError:、跳过、倒计时关闭以及主动放弃等待都应汇入宿主的“继续主流程”出口。以下代码展示对象管理与展示调用;将 clearSplash 后的业务导航接到自己的入口,保证一次广告机会只推进一次业务。视频完播和点击跳转不等于广告关闭。
以下示例放入一个 .m 文件,在宿主的加载时机调用 loadSplash,并将广告位替换为平台分配值。完整的可运行页面与手动 Load/Show 操作见 Simple。
#import <YSIFLYADLib/YSIFLYADLib.h>
@interface SplashExampleViewController : UIViewController <YSIFLYSplashAdDelegate>
@property (nonatomic, strong) YSIFLYSplashAd *splashAd;
@property (nonatomic, assign) BOOL splashReady;
@end
@implementation SplashExampleViewController
// 在宿主隐私流程完成、页面可展示时调用。
- (void)loadSplash {
[self clearSplash];
self.splashAd = [[YSIFLYSplashAd alloc] initWithAdUnitId:@"YOUR_SPLASH_AD_UNIT_ID"];
self.splashAd.delegate = self;
self.splashAd.currentViewController = self;
YSIFLYAdRequestConfig *request = [[YSIFLYAdRequestConfig alloc] init];
request.requestTimeout = @5;
[self.splashAd ysifly_loadAdWithRequestConfig:request];
}
- (void)ysifly_splashAdDidReady:(YSIFLYSplashAd *)ad {
if (ad != self.splashAd) return;
self.splashReady = YES;
[self tryShowSplash];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self tryShowSplash]; // Ready 先到、页面后出现时再次检查。
}
- (void)tryShowSplash {
YSIFLYSplashAd *ad = self.splashAd;
if (!ad || !self.splashReady || ![ad ysifly_isAdValid] || !self.view.window ||
self.presentedViewController ||
UIApplication.sharedApplication.applicationState != UIApplicationStateActive) return;
if (@available(iOS 13.0, *)) {
if (self.view.window.windowScene.activationState != UISceneActivationStateForegroundActive) return;
}
self.splashReady = NO; // 每次广告机会只发起一次展示。
YSIFLYSplashAdConfig *config = [[YSIFLYSplashAdConfig alloc] init];
config.traceDuration = 5;
config.muteOnStart = YES;
config.muteButtonHidden = NO;
[ad ysifly_showAdFromRootViewController:self config:config];
}
- (void)ysifly_splashAd:(YSIFLYSplashAd *)ad didFailWithError:(YSIFLYAdError *)error {
if (ad != self.splashAd) return;
NSLog(@"Splash failed: %d %@", error.errorCode, error.errorDescription);
[self clearSplash]; // 宿主在此继续主流程,避免失败后停在启动页。
}
- (void)ysifly_splashAdDidClose:(YSIFLYSplashAd *)ad {
if (ad == self.splashAd) [self clearSplash];
}
- (void)ysifly_splashAdDidSkip:(YSIFLYSplashAd *)ad {
if (ad == self.splashAd) [self clearSplash];
}
- (void)clearSplash {
self.splashReady = NO;
self.splashAd.delegate = nil;
[self.splashAd ysifly_destroy];
self.splashAd = nil;
}
- (void)dealloc {
[self.splashAd ysifly_destroy];
}
@end展示配置与回调
| 配置/回调 | 含义与接入动作 |
|---|---|
traceDuration | 倒计时秒数,有效范围 3~5;默认 5,越界回退为 5 |
mediumBottomView | 宿主品牌区,需由媒体设置视图高度;示例提供 Logo 区域 |
customWindow | 可选展示窗口;默认使用传入控制器所属 window |
muteOnStart / muteButtonHidden | 视频初始静音状态、静音按钮是否隐藏 |
ysifly_splashAdDidLoad: | 响应解析成功,可读 bidInfo 和 hasVideoTemplate,尚不能据此展示 |
ysifly_splashAdDidReady: | 主素材已就绪;检查广告有效性与宿主可展示状态 |
ysifly_splashAdDidShow: / ysifly_splashAdDidExpose: | 已显示到 window / 已达到有效曝光,是两个事件 |
ysifly_splashAdDidSkip: | 用户点击跳过,广告关闭 |
ysifly_splashAdDidClose: | 倒计时结束并关闭;不要把视频完播或跳转等同于本回调 |
ysifly_splashAd:didJumpWithSuccess: | 点击跳转结果;SDK 负责跳转及回退,媒体不要再次打开链接 |
ysifly_splashAdDidPlayFinish: | 视频播放完成,广告仍可保留末帧与交互,不表示关闭 |
ysifly_splashAd:didFailWithError: | 统一加载/展示失败出口,记录错误并继续宿主流程 |
可左右滚动查看完整表格
回调在主线程触发。强持有广告对象,并在展示前核对回调中的对象是否仍是当前实例。展示时传入已加入 window 的控制器;SDK 将开屏覆盖到窗口,无需宿主另外 present 广告控制器。
ysifly_isAdValid 仅表示实例当前是否可展示,不代替 Ready 和宿主可见性判断。成功展示后需要新建实例发起下一次请求。取消请求、宿主永久结束广告流程或释放页面时调用 ysifly_destroy;销毁后该对象不可恢复。不要仅因为广告打开了落地页就销毁仍在使用的广告。