// // RQADViewManager.m // jiaPei // // Created by 张嵘 on 2021/4/29. // Copyright © 2021 JCZ. All rights reserved. // #import "RQADViewManager.h" #import #import #import #import #import #import #import #import "YYTimer.h" // 支持广点通开屏广告v+ #define SUPPORT_SPLASH_ZOOMOUT 1 #if defined(__IPHONE_14_0) #import //适配iOS14 #endif static RQADViewManager *manger = nil; static dispatch_once_t onceToken; static NSString *appId = @"3206311"; static NSString *splashPlcId = @"7baf358edd3600ff50"; static NSString *bannerPlcId = @"f2889056c5a7331f1e"; static NSString *nativeAdPlcId = @"2d2e5b5eb5d2ba10c6"; static NSString *homePageNativeAdPlcId = @"bd37f94cd1cf693488"; static NSString *fullScreenvodAdPlcId = @"2f9dd9678f50239cdb"; static NSString *intertitialAdPlcId = @"dbdadc0f30655a8d7e"; //插屏开屏广告 static NSString *intertitialSplashAdPlcId = @"8f2d81c8b6275b6d80"; @interface RQADViewManager () /* 插屏广告 */ @property (nonatomic, readwrite, strong) ADSuyiSDKIntertitialAd *intertitialAd; /* 开屏广告对象 */ @property (nonatomic, readwrite, strong) ADSuyiSDKSplashAd *splashAd; /* 横幅广告 */ @property (nonatomic, readwrite, strong) ADSuyiSDKBannerAdView *bannerView; /* 信息流广告 */ @property (nonatomic, readwrite, strong) ADSuyiSDKNativeAd *nativeAd; /* 全屏视频广告 */ @property (nonatomic, readwrite, strong) ADSuyiSDKFullScreenVodAd *fullScreenvodAd; @property (nonatomic, readwrite, strong) UIView *currentAdView; @property (nonatomic, readwrite, strong) UIView *customView; @property (nonatomic ,strong) dispatch_source_t myTimer;// 注意:此处应该使用强引用 strong @property (nonatomic, readwrite, assign) BOOL isResume; @property (nonatomic, readwrite, assign) RQADType adType; @property (nonatomic, readwrite, strong) RQADCloseCompletedBlock aDCloseCompletedBlock; @property (nonatomic, readwrite, strong) UIButton *skipBtn; @property (nonatomic, readwrite, strong) YYTimer *timer; @property (nonatomic, readwrite, assign) NSUInteger count; @property (nonatomic, readwrite, assign) BOOL isReady; @property (nonatomic, readwrite, assign) BOOL isCanShow; @end @implementation RQADViewManager #pragma mark - SystemMethod + (RQADViewManager *)sharedManager { dispatch_once(&onceToken, ^{ manger = [[self alloc] init]; }); return manger; } - (instancetype)init { self = [super init]; if (self) { [self initBaseData]; } return self; } - (void)dealloc { [self stopTimer]; } #pragma mark - PublicMethods - (void)loadAdWithAdType:(RQADType)adType customView:(UIView * _Nullable )customView { [self loadAdWithAdType:adType customView:customView cycleSecound:0.f]; } - (void)loadAdWithAdType:(RQADType)adType customView:(UIView * _Nullable )customView cycleSecound:(CGFloat)second { self.adType = adType; self.customView = customView; /// 服务端允许展示广告 // if (RQ_SHARE_FUNCTION.APP_AD) { // // } switch (adType) { case RQADType_Splash: { /// 不展示广告在有引导页的时候 // if (!myDelegate.adIsShow) { // [self setThirtyPartySdk]; // } [self setThirtyPartySdk]; break; } case RQADType_Banner: { [self.bannerView removeFromSuperview]; self.bannerView.delegate = nil; self.bannerView = nil; [self.customView addSubview:self.bannerView]; [self.bannerView loadAndShowWithError:nil]; break; } case RQADType_native: case RQADType_HomePage_native:{ if (self.currentAdView) { [self.currentAdView removeFromSuperview]; self.currentAdView = nil; self.nativeAd = nil; } [self.nativeAd load:1]; } break; case RQADType_fullScreen: { [self.fullScreenvodAd loadAdData]; } break; case RQADType_Interstitial: { self.isReady = NO; _intertitialAd = nil; [self.intertitialAd loadAdData]; } break; case RQADType_InterstitialSplash: { [self setThirtyPartySdk]; } break; default: break; } } - (void)showAdWithAdType:(RQADType)adType { switch (adType) { case RQADType_Interstitial: { if (self.isReady) { self.isCanShow = YES; [self.intertitialAd show]; } } break; default: break; } } - (void)initCloseBlock:(RQADCloseCompletedBlock)block { self.aDCloseCompletedBlock = block; } #pragma mark - Action - (void)_timerValueChanged:(YYTimer *)timer { self.count--; if (self.count == 0) { [timer invalidate]; self.timer = nil; [self.skipBtn setTitleNormal:@"跳过"]; if (self.currentAdView) { [self.currentAdView adsy_close]; } return; } [self.skipBtn setTitleNormal:[NSString stringWithFormat:@"跳过 %zd", self.count]]; } #pragma mark - PrivateMethods - (void)setThirtyPartySdk { if ([self isFirstAppLoad]) { [self showAgreePrivacy]; }else { [self initADSuyiSDK]; } } - (void)initADSuyiSDK { @weakify(self) dispatch_async(dispatch_get_main_queue(), ^{ @strongify(self) // 设置日志输出等级 [ADSuyiSDK setLogLevel:ADSuyiKitLogLevelDebug]; // ADSuyiSDK初始化 [ADSuyiSDK initWithAppId:appId completionBlock:^(NSError * _Nonnull error) { if (error) { NSLog(@"SDK 初始化失败:%@", error.localizedDescription); } }]; /* * 推荐在AppDelegate中的最后加载开屏广告 * 其他的接入方式会有需要特殊注意的方式,遇到过的相关问题在SDK相关问题的文档中有提到 */ if (_adType == RQADType_InterstitialSplash) { self.isReady = NO; _intertitialAd = nil; [self.intertitialAd loadAdData]; } else { [self loadSplashAd]; } }); } - (void)showAgreePrivacy { @weakify(self) // 隐私合规化示例 // 隐私合规化示例 NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; // app名称 NSString *app_Name = [infoDictionary objectForKey:@"CFBundleDisplayName"]; NSString *messageStr = [NSString stringWithFormat:@"亲爱的用户,欢迎您信任并使用【%@】,我们依据相关法律制定了《用户协议》和《隐私协议》帮你你了解我们手机,使用,存储和共享个人信息情况,请你在点击之前仔细阅读并理解相关条款。\n1、在使用我们的产品和服务时,将会提供与具体功能有关的个法人信息(可能包括身份验证,位置信息,设备信息和操作日志等)\n2、我们会采用业界领先的安全技术来保护你的个人隐私,未经授权许可我们不会讲上述信息共享给任何第三方或用于未授权的其他用途。\n如你同意请点击同意按钮并继续。",app_Name]; UIAlertController *alertVc = [UIAlertController alertControllerWithTitle:@"温馨提示" message:messageStr preferredStyle:(UIAlertControllerStyleAlert)]; UIAlertAction *cancle = [UIAlertAction actionWithTitle:@"不同意" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:@"点击同意才能使用该App服务" preferredStyle:(UIAlertControllerStyleAlert)]; UIAlertAction *sure = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleCancel) handler:^(UIAlertAction * _Nonnull action) { [RQControllerHelper.currentViewController presentViewController:alertVc animated:YES completion:nil]; }]; [alert addAction:sure]; [RQControllerHelper.currentViewController presentViewController:alert animated:YES completion:nil]; }]; UIAlertAction *agree = [UIAlertAction actionWithTitle:@"同意并继续" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) { @strongify(self) // 记录是否第一次启动 [self writeAppLoad]; // 获取idfa权限 建议启动就获取权限 不获取权限会影响收益 if (@available(iOS 14.0, *)) { [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) { }]; } // 用户同意隐私后 初始化 [self initADSuyiSDK]; }]; [alertVc addAction:cancle]; [alertVc addAction:agree]; [RQControllerHelper.currentViewController presentViewController:alertVc animated:YES completion:nil]; } #pragma mark -- helper - (void)writeAppLoad { NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults]; [userDefault setObject:@"yes" forKey:@"isFirstLoad"]; [userDefault synchronize]; } - (BOOL)isFirstAppLoad { NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults]; if ([[userDefault objectForKey:@"isFirstLoad"] isEqualToString:@"yes"]) { return NO; } return YES; } - (void)loadSplashAd { if (self.splashAd) { return; } // 1、初始化开屏广告实例对象 self.splashAd = [[ADSuyiSDKSplashAd alloc]init]; self.splashAd.delegate = self; #ifdef SUPPORT_SPLASH_ZOOMOUT self.splashAd.zoomOutViewDelegate = self; #endif self.splashAd.controller = RQControllerHelper.currentViewController; // 2、设置开屏的广告位id self.splashAd.posId = splashPlcId; /** 开屏请求总超时时间:所有平台轮询的请求等待总时长(不包括图片渲染时间),单位秒,推荐设置为4s,最小值为3s 开屏各平台分配逻辑:(目前只有开屏需要分配时间,并且理论上分配给到各平台的超时时间不会完全耗尽) 1、3<=tolerateTimeout<=4:轮询首位平台的超时时间为(tolerateTimeout-1)s,次位为2s,如果后续还有平台统一为1s; 2、tolerateTimeout>=5:轮询首位平台的超时时间为(tolerateTimeout-2)s,次位为3s,如果后续还有平台统一为2s; */ self.splashAd.tolerateTimeout = 4; // 3、设置默认启动图(一般设置启动图的平铺颜色为背景颜色,使得视觉效果更加平滑) UIViewController * vc = [[UIStoryboard storyboardWithName:@"LaunchScreen" bundle:[NSBundle mainBundle]] instantiateInitialViewController]; CGRect rect = [UIScreen mainScreen].bounds; UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0.0f); CGContextRef context = UIGraphicsGetCurrentContext(); vc.view.frame = rect; [vc.view.layer renderInContext:context]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); self.splashAd.backgroundColor = [UIColor adsy_getColorWithImage:image withNewSize:[UIScreen mainScreen].bounds.size]; // 4、开屏广告机型适配 CGFloat bottomViewHeight; // if (kADSYCurveScreen) { // 刘海屏 bottomViewHeight = [UIScreen mainScreen].bounds.size.height * 0.15; // } else { // bottomViewHeight = [UIScreen mainScreen].bounds.size.height - [UIScreen mainScreen].bounds.size.width * (960 / 640.0); // } // 6、设置开屏保底逻辑(可选) /** *功能说明:App在首次启动时,需要先请求获取广告位配置文件后,然后再去请求开屏广告,也就是首次加载开屏广告时需要两次串行网络请求,因此很容易因超时导致开屏广告展示失败。 *解决方案:为避免开屏超时问题,开放此设置给开发者,开发者可以根据实际需求选择一家广告平台,通过API接口将必需参数传递给Suyi聚合SDK。(该设置只能指定一家广告平台,并且首次启动时只会请求该平台的广告,但App首次开屏广告将不受ADmobile后台控制,包括下载提示,广告位关闭。) *该设置仅会在首次加载开屏广告时,SDK会使用开发者传入的参数进行广告请求,同时获取后台配置文件的广告配置信息缓存到本地(首次请求广告平台广告和获取配置信息时并发进行),后续的开屏广告将按照缓存缓存的后台广告位配置顺序进行开屏广告请求。 *支持穿山甲、优量汇、快手、百度 */ [self.splashAd setBottomSplashWithSuyiPosid:splashPlcId platformListId:@"5237499" platform:@"csjad" appId:@"5237499" appKey:nil platformPosid:@"887634083" renderType:ADSuyiSplashRenderTypeExpressPro]; // 7、加载开屏广告 [self.splashAd loadAndShowInWindow:RQ_APPDELEGATE.window]; } - (void)initBaseData { [[[[[RQNotificationCenter rac_addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil] takeUntil:self.rac_willDeallocSignal] map:^id(NSNotification *value) { return value.object; }] distinctUntilChanged] subscribeNext:^(id x) { NSLog(@"%@",@"APP进入后台"); }]; } //获取当前屏幕显示的viewcontroller - (UIViewController *)getCurrentVC { UIViewController *resultVC; resultVC = [self _topViewController:[[UIApplication sharedApplication].keyWindow rootViewController]]; /// RQ Fixed : 这里必须要判断一下,否则取出来永远都是 RQMainTabBarViewController。这是架构上小缺(特)陷(性)。因为RQMainTabBarViewController的子控制器是UITabBarController,所以需要递归UITabBarController的所有的子控制器 if ([resultVC isKindOfClass:[RQTableViewController class]]) { RQTableViewController *mainVc = (RQTableViewController *)resultVC; resultVC = [self _topViewController:mainVc.tabBarController]; } return resultVC; } - (UIViewController *)_topViewController:(UIViewController *)vc { if ([vc isKindOfClass:[UINavigationController class]]) { return [self _topViewController:[(UINavigationController *)vc topViewController]]; } else if ([vc isKindOfClass:[UITabBarController class]]) { return [self _topViewController:[(UITabBarController *)vc selectedViewController]]; } else { return vc; } } - (void)initTimerWithSecound:(CGFloat)second { //2.设置时间等 /* 第一个参数:定时器对象 第二个参数:DISPATCH_TIME_NOW 表示从现在开始计时 第三个参数:间隔时间 GCD里面的时间最小单位为 纳秒 第四个参数:精准度(表示允许的误差,0表示绝对精准) */ dispatch_source_set_timer(self.myTimer, DISPATCH_TIME_NOW, second * NSEC_PER_SEC, 0 * NSEC_PER_SEC); //3.要调用的任务 dispatch_source_set_event_handler(self.myTimer, ^{ NSLog(@"GCD-----%@",[NSThread currentThread]); // [self.bannerAdManager loadNativeAd]; // if (![[self getCurrentVC] isKindOfClass:[ExerciseVC class]]) { // NSLog(@"%s",object_getClassName([self getCurrentVC])); // [self stopTimer]; // } }); } - (void)pauseTimer { if (self.myTimer) { dispatch_suspend(_myTimer); } } - (void)resumeTimer { if (_myTimer) { dispatch_resume(_myTimer); self.isResume = YES; } } - (void)stopTimer { self.isResume = NO; if (_myTimer) { dispatch_source_cancel(_myTimer); _myTimer = nil; } } #pragma mark - ADSuyiSDKSplashAdDelegate /** 开屏展现成功 @param splashAd 广告实例 */ - (void)adsy_splashAdSuccessToPresentScreen:(ADSuyiSDKSplashAd *)splashAd{ #ifdef SUPPORT_SPLASH_ZOOMOUT if(splashAd.splashZoomOutView) { UIViewController *rootVc = [UIApplication sharedApplication].keyWindow.rootViewController; [rootVc.view addSubview:splashAd.splashZoomOutView]; } #endif } /** 开屏展现失败 @param splashAd 广告实例 @param error 具体错误信息 */ - (void)adsy_splashAdFailToPresentScreen:(ADSuyiSDKSplashAd *)splashAd failToPresentScreen:(ADSuyiAdapterErrorDefine *)error{ _splashAd = nil; } /** 开屏广告点击 @param splashAd 广告实例 */ - (void)adsy_splashAdClicked:(ADSuyiSDKSplashAd *)splashAd{ } /** 开屏被关闭 @param splashAd 广告实例 */ - (void)adsy_splashAdClosed:(ADSuyiSDKSplashAd *)splashAd{ #ifdef SUPPORT_SPLASH_ZOOMOUT if(_splashAd.splashZoomOutView == nil) _splashAd = nil; #else _splashAd = nil; #endif } /** 开屏展示 @param splashAd 广告实例 */ - (void)adsy_splashAdEffective:(ADSuyiSDKSplashAd *)splashAd{ } #ifdef SUPPORT_SPLASH_ZOOMOUT #pragma mark - ADSuyiSDKSplashAdZoomOutViewDelegate /** ZoomOutView被点击 @param splashAd 广告实例 @param splashZoomOutView zoomOutView */ - (void)adsy_splashZoomOutViewDidClick:(ADSuyiSDKSplashAd *)splashAd splashZoomOutView:(__kindof UIView *)splashZoomOutView { } /** ZoomOutView 被关闭 @param splashAd 广告实例 @param splashZoomOutView zoomOutView */ - (void)adsy_splashZoomOutViewAdDidClose:(ADSuyiSDKSplashAd *)splashAd splashZoomOutView:(__kindof UIView *)splashZoomOutView { } /** ZoomOutView 播放完成 @param splashAd 广告实例 @param splashZoomOutView zoomOutView */ - (void)adsy_splashZoomOutViewAdVideoFinished:(ADSuyiSDKSplashAd *)splashAd splashZoomOutView:(__kindof UIView *)splashZoomOutView { } /** ZoomOutView 进入视频详情页 @param splashAd 广告实例 @param splashZoomOutView zoomOutView */ - (void)adsy_splashZoomOutViewAdDidPresentFullScreenModal:(ADSuyiSDKSplashAd *)splashAd splashZoomOutView:(__kindof UIView *)splashZoomOutView { } /** ZoomOutView 退出视频详情页 @param splashAd 广告实例 @param splashZoomOutView zoomOutView */ - (void)adsy_splashZoomOutViewAdDidDismissFullScreenModal:(ADSuyiSDKSplashAd *)splashAd splashZoomOutView:(__kindof UIView *)splashZoomOutView { _splashAd = nil; } #endif #pragma mark - ADSuyiSDKBannerAdViewDelegate /** 广告获取成功 @param bannerView banner实例 */ - (void)adsy_bannerViewDidReceived:(ADSuyiSDKBannerAdView *)bannerView{ } /** 广告拉取失败 @param bannerView banner实例 @param errorModel 错误描述 */ - (void)adsy_bannerViewFailToReceived:(ADSuyiSDKBannerAdView *)bannerView errorModel:(ADSuyiAdapterErrorDefine *)errorModel{ NSLog(@"adsy_bannerViewFailToReceived:%@, %@",errorModel.errorDescription, errorModel.errorDetailDict); [_bannerView removeFromSuperview]; _bannerView = nil; } /** 广告点击 @param bannerView 广告实例 */ - (void)adsy_bannerViewClicked:(ADSuyiSDKBannerAdView *)bannerView{ } /** 广告关闭 @param bannerView 广告实例 */ - (void)adsy_bannerViewClose:(ADSuyiSDKBannerAdView *)bannerView{ _bannerView = nil; } /** 广告展示 @param bannerView 广告实例 */ - (void)adsy_bannerViewExposure:(ADSuyiSDKBannerAdView *)bannerView{ } #pragma mark - ADSuyiSDKNativeAdDelegate - (void)adsy_nativeAdSucessToLoad:(ADSuyiSDKNativeAd *)nativeAd adViewArray:(NSArray<__kindof UIView *> *)adViewArray { for (UIView *adView in adViewArray) { // 4、判断信息流广告是否为自渲染类型(可选实现) 可仿照所示样式demo实现 如无所需样式则需自行实现 // 如果单纯只配置了模版信息流,那么不需要实现,如果配置了自渲染信息流,那么需要实现 if(adView.renderType == ADSuyiAdapterRenderTypeNative) { // 4.1、如果是自渲染类型则可样式自定义(3种示例demo样式见下) // 1、常规样式 // [self setUpUnifiedTopImageNativeAdView:adView]; // 2、纯图样式 [self setUpUnifiedOnlyImageNativeAdView:adView]; // 3、上图下文 // [self setUpUnifiedTopImageNativeAdView:adView]; } // 5、注册,自渲染:注册点击事件,模板:render,重要 [adView adsy_registViews:@[adView]]; // 广点通视频信息流广告会给mediaView添加事件,点击会出现半屏广告,以下为广点通官方给予的解决方案 if([adView.adsy_platform isEqualToString:ADSuyiAdapterPlatformGDT] && adView.renderType == ADSuyiAdapterRenderTypeNative && adView.data.shouldShowMediaView) { UIView *mediaView = [adView adsy_mediaViewForWidth:0.0]; mediaView.userInteractionEnabled = NO; } } } - (void)adsy_nativeAdFailToLoad:(ADSuyiSDKNativeAd *)nativeAd errorModel:(ADSuyiAdapterErrorDefine *)errorModel { self.aDCloseCompletedBlock? self.aDCloseCompletedBlock(RQADDoType_Faild) : nil; } - (void)adsy_nativeAdViewRenderOrRegistSuccess:(UIView *)adView { self.currentAdView = adView; [self.customView addSubview:self.currentAdView]; } - (void)adsy_nativeAdViewRenderOrRegistFail:(UIView *)adView { self.currentAdView = adView; self.aDCloseCompletedBlock? self.aDCloseCompletedBlock(RQADDoType_Faild) : nil; } - (void)adsy_nativeAdClicked:(ADSuyiSDKNativeAd *)nativeAd adView:(__kindof UIView *)adView { self.currentAdView = adView; [adView adsy_close]; } - (void)adsy_nativeAdClose:(ADSuyiSDKNativeAd *)nativeAd adView:(__kindof UIView *)adView { if (self.adType == RQADType_native) { if (self.currentAdView) { self.aDCloseCompletedBlock? self.aDCloseCompletedBlock(RQADDoType_Close) : nil; self.currentAdView = adView; [self.currentAdView removeFromSuperview]; [self.skipBtn removeFromSuperview]; self.currentAdView = nil; self.nativeAd = nil; } } else { if (self.currentAdView) { self.aDCloseCompletedBlock? self.aDCloseCompletedBlock(RQADDoType_Close) : nil; self.currentAdView = adView; [self.currentAdView removeFromSuperview]; self.currentAdView = nil; self.nativeAd = nil; } } } - (void)adsy_nativeAdExposure:(ADSuyiSDKNativeAd *)nativeAd adView:(__kindof UIView *)adView { if (self.adType == RQADType_native) { self.currentAdView = adView; [self.customView bringSubviewToFront:self.skipBtn]; self.count = 5; [_skipBtn setTitleNormal:@"跳过 5"]; self.timer = [YYTimer timerWithTimeInterval:1 target:self selector:@selector(_timerValueChanged:) repeats:YES]; self.aDCloseCompletedBlock? self.aDCloseCompletedBlock(RQADDoType_Success) : nil; } } #pragma mark - Helper 自渲染类型信息流处理方法 setUpUnifiedOnlyImageNativeAdView纯图样式 // 纯图样式 - (void)setUpUnifiedOnlyImageNativeAdView:(UIView *)adView { // 设计的adView实际大小,其中宽度和高度可以自己根据自己的需求设置 CGFloat adWidth = self.customView.frame.size.width; CGFloat adHeight = adWidth / 16.0 * 9; adView.frame = CGRectMake(0, 0, adWidth, adHeight); // 设置主图/视频(主图可选,但强烈建议带上,如果有视频试图,则必须带上) CGRect mainFrame = CGRectMake(0, 0, adWidth, adHeight); if(adView.data.shouldShowMediaView) { UIView *mediaView = [adView adsy_mediaViewForWidth:mainFrame.size.width]; mediaView.frame = mainFrame; [adView addSubview:mediaView]; } else { UIImageView *imageView = [UIImageView new]; imageView.backgroundColor = [UIColor adsy_colorWithHexString:@"#CCCCCC"]; [adView addSubview:imageView]; imageView.frame = mainFrame; NSString *urlStr = adView.data.imageUrl; if(urlStr.length > 0) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:urlStr]]]; dispatch_async(dispatch_get_main_queue(), ^{ imageView.image = image; }); }); } } // 展示关闭按钮(必要) [self.customView addSubview:self.skipBtn]; self.skipBtn.frame = CGRectMake(adWidth - 12 - 54, 12, 54, 27); [self.skipBtn addTarget:adView action:@selector(adsy_close) forControlEvents:UIControlEventTouchUpInside]; // 显示logo图片(必要) if(![adView.adsy_platform isEqualToString:ADSuyiAdapterPlatformGDT]) { // 优量汇(广点通)会自带logo,不需要添加 UIImageView *logoImage = [UIImageView new]; [adView addSubview:logoImage]; // [adView bringSubviewToFront:logoImage]; [adView adsy_platformLogoImageDarkMode:NO loadImageBlock:^(UIImage * _Nullable image) { CGFloat maxWidth = 40; CGFloat logoHeight = maxWidth / image.size.width * image.size.height; logoImage.frame = CGRectMake(adWidth - maxWidth, adHeight - logoHeight, maxWidth, logoHeight); logoImage.image = image; }]; } } #pragma mark - ADSuyiSDKFullScreenVodAdDelegate /** ADSuyiSDKFullScreenVodAd请求成功回调 @param fullScreenVodAd 全屏视频广告实例对象 */ - (void)adsy_fullScreenVodAdSuccedToLoad:(ADSuyiSDKFullScreenVodAd *)fullScreenVodAd{ } /** ADSuyiSDKFullScreenVodAd准备好被播放 @param fullScreenVodAd 全屏视频广告实例对象 */ - (void)adsy_fullScreenVodAdReadyToPlay:(ADSuyiSDKFullScreenVodAd *)fullScreenVodAd{ // 3、推荐在准备好被播放会调用展示激励视频广告 [_fullScreenvodAd show]; } /** ADSuyiSDKFullScreenVodAd视频加载成功回调 @param fullScreenVodAd 全屏视频广告实例对象 */ - (void)adsy_fullScreenVodAdSuccessToLoadVideo:(ADSuyiSDKFullScreenVodAd *)fullScreenVodAd{ // 3、也可在视频加载成功回调中展示激励视频广告 } /** ADSuyiSDKFullScreenVodAd请求失败回调 @param fullScreenVodAd 全屏视频广告实例对象 @param error 失败原因 */ - (void)adsy_fullScreenVodAdFailedToLoad:(ADSuyiSDKFullScreenVodAd *)fullScreenVodAd error:(ADSuyiAdapterErrorDefine *)error{ // 4、广告内存回收 _fullScreenvodAd = nil; } /** ADSuyiSDKFullScreenVodAd展示在屏幕内回调 @param fullScreenVodAd 全屏视频广告实例对象 */ - (void)adsy_fullScreenVodAdDidPresent:(ADSuyiSDKFullScreenVodAd *)fullScreenVodAd{ } /** ADSuyiSDKFullScreenVodAd展示失败回调 @param fullScreenVodAd 全屏视频广告实例对象 @param error 失败原因 */ - (void)adsy_fullScreenVodAdFailToPresent:(ADSuyiSDKFullScreenVodAd *)fullScreenVodAd error:(NSError *)error{ } /** ADSuyiSDKFullScreenVodAd点击回调 @param fullScreenVodAd 全屏视频广告实例对象 */ - (void)adsy_fullScreenVodAdDidClick:(ADSuyiSDKFullScreenVodAd *)fullScreenVodAd{ } /** ADSuyiSDKFullScreenVodAd关闭回调 @param fullScreenVodAd 全屏视频广告实例对象 */ - (void)adsy_fullScreenVodAdDidClose:(ADSuyiSDKFullScreenVodAd *)fullScreenVodAd{ // 4、广告内存回收 _fullScreenvodAd = nil; } /** ADSuyiSDKFullScreenVodAd展示回调 @param fullScreenVodAd 广告实例 */ - (void)adsy_fullScreenVodAdExposure:(ADSuyiSDKFullScreenVodAd *)fullScreenVodAd{ } /** ADSuyiSDKFullScreenVodAd播放完成回调 @param fullScreenVodAd 广告实例 @param error 失败原因(如果为nil,则是单纯的播放完成) */ - (void)adsy_fullScreenVodAdPlayComplete:(ADSuyiSDKFullScreenVodAd *)fullScreenVodAd didFailed:(NSError *_Nullable)error{ } #pragma mark - ADSuyiSDKIntertitialAdDelegate /** ADSuyiSDKIntertitialAd请求成功回调 @param interstitialAd 插屏广告实例对象 */ - (void)adsy_interstitialAdSuccedToLoad:(ADSuyiSDKIntertitialAd *)interstitialAd { self.isReady = YES; if (!RQ_Video_Module.playerController.isPlaying && self.adType == RQADType_Interstitial && self.isCanShow && _intertitialAd) { [_intertitialAd show]; } } /** ADSuyiSDKIntertitialAd请求失败回调 @param interstitialAd 插屏广告实例对象 @param error 失败原因 */ - (void)adsy_interstitialAdFailedToLoad:(ADSuyiSDKIntertitialAd *)interstitialAd error:(ADSuyiAdapterErrorDefine *)error { _intertitialAd = nil; } /** ADSuyiSDKIntertitialAd展示在屏幕内回调 @param interstitialAd 插屏广告实例对象 */ - (void)adsy_interstitialAdDidPresent:(ADSuyiSDKIntertitialAd *)interstitialAd { } /** ADSuyiSDKIntertitialAd展示在屏幕内失败回调 @param interstitialAd 插屏广告实例对象 */ - (void)adsy_interstitialAdFailedToPresent:(ADSuyiSDKIntertitialAd *)interstitialAd error:(NSError *)error { } /** ADSuyiSDKIntertitialAd点击回调 @param interstitialAd 插屏广告实例对象 */ - (void)adsy_interstitialAdDidClick:(ADSuyiSDKIntertitialAd *)interstitialAd { } /** ADSuyiSDKIntertitialAd关闭回调 @param interstitialAd 插屏广告实例对象 */ - (void)adsy_interstitialAdDidClose:(ADSuyiSDKIntertitialAd *)interstitialAd { } /** ADSuyiSDKIntertitialAd展示回调 @param interstitialAd 广告实例 */ - (void)adsy_interstitialAdExposure:(ADSuyiSDKIntertitialAd *)interstitialAd { } #pragma mark - LazyLoad - (dispatch_source_t)myTimer { if (!_myTimer) { //0.创建队列 dispatch_queue_t queue = dispatch_get_main_queue(); //1.创建GCD中的定时器 /* 第一个参数:创建source的类型 DISPATCH_SOURCE_TYPE_TIMER:定时器 第二个参数:0 第三个参数:0 第四个参数:队列 */ _myTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); } return _myTimer; } - (UIView *)customView { if (!_customView) { CGRect rect; switch (self.adType) { case RQADType_Splash: rect = CGRectMake(0, 0, RQ_SCREEN_WIDTH, RQ_SCREEN_HEIGHT * 0.75); break; case RQADType_Banner: rect = CGRectMake(25, (RQ_SCREEN_HEIGHT - RQ_APPLICATION_TOP_BAR_HEIGHT - RQ_APPLICATION_SAFEAREA_BOTTOM_HEIGHT) - 60 - 40, RQ_SCREEN_WIDTH - 50, 50); default: rect = CGRectMake(0, 0, RQ_SCREEN_WIDTH, RQ_SCREEN_HEIGHT); break; } _customView = [[UIView alloc] initWithFrame:rect]; } return _customView; } - (ADSuyiSDKBannerAdView *)bannerView { if (!_bannerView) { // 1、初始化banner视图,并给定frame值,rate取值根据banner的尺寸 _bannerView = [[ADSuyiSDKBannerAdView alloc] initWithFrame:CGRectMake(0, 0, RQ_SCREEN_WIDTH - 50, (RQ_SCREEN_WIDTH - 50) / (640/100.0))]; _bannerView.delegate = self; // 2、设置控制器,用来弹出落地页,重要 _bannerView.controller = RQControllerHelper.currentViewController; // 3、设置广告位id,重要 _bannerView.posId = bannerPlcId; // 可设置bannerview的背景色,请按需添加修改该行代码 _bannerView.backgroundColor = UIColor.whiteColor; } return _bannerView; } - (ADSuyiSDKNativeAd *)nativeAd { if (!_nativeAd) { _nativeAd = [[ADSuyiSDKNativeAd alloc] initWithAdSize:self.customView.size]; _nativeAd.delegate = self; _nativeAd.controller = RQControllerHelper.currentViewController; _nativeAd.posId = (self.adType == RQADType_HomePage_native)? homePageNativeAdPlcId : nativeAdPlcId; } return _nativeAd; } - (ADSuyiSDKFullScreenVodAd *)fullScreenvodAd { if (!_fullScreenvodAd) { _fullScreenvodAd = [ADSuyiSDKFullScreenVodAd new]; _fullScreenvodAd.controller = RQControllerHelper.currentViewController; _fullScreenvodAd.posId = fullScreenvodAdPlcId; _fullScreenvodAd.delegate = self; _fullScreenvodAd.tolerateTimeout = 4; } return _fullScreenvodAd; } - (ADSuyiSDKIntertitialAd *)intertitialAd { if (!_intertitialAd) { _intertitialAd = [ADSuyiSDKIntertitialAd new]; UIViewController *vc = RQControllerHelper.currentViewController; _intertitialAd.controller = vc; _intertitialAd.posId = (_adType == RQADType_InterstitialSplash)? intertitialAdPlcId : intertitialAdPlcId; _intertitialAd.delegate = self; _intertitialAd.tolerateTimeout = 4; _intertitialAd.adSize = CGSizeMake(vc.view.frame.size.width, vc.view.frame.size.height); } return _intertitialAd; } - (UIButton *)skipBtn { if (!_skipBtn) { _skipBtn = [UIButton buttonWithType:UIButtonTypeCustom]; _skipBtn.frame = CGRectMake(RQ_SCREEN_WIDTH - 54 - 12, 12, 54, 27); [_skipBtn setBackgroundColor:[UIColor colorWithWhite:0.1 alpha:0.3]]; // [_skipBtn setBackgroundImage:[UIImage imageWithColor:[UIColor colorWithWhite:0.1 alpha:1] size:CGSizeMake(200, 200)] forState:UIControlStateNormal]; _skipBtn.titleLabel.font = RQRegularFont(13); [_skipBtn setTitleNormal:@"跳过 5"]; _skipBtn.layer.cornerRadius = 13.5; _skipBtn.clipsToBounds = YES; } return _skipBtn; } @end