Day_Count_Memory_Days/anniversary_Project/LuxADManager/LuxADConfigure.m
2024-08-19 14:39:54 +08:00

460 lines
17 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// AppDelegate+LuxAppDelegate.m
// TallPaper
//
// Created by aaa on 2024/7/30.
//
#import "LuxADConfigure.h"
#import <objc/runtime.h>
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <AdSupport/ASIdentifierManager.h>
#import <Firebase/Firebase.h>
#import <FirebaseCore/FirebaseCore.h>
#import <FirebaseRemoteConfig/FirebaseRemoteConfig.h>
#import <FirebaseAnalytics/FirebaseAnalytics.h>
//替换为自己需要用到的VC类头文件
#import "OneVC.h"
#import "twoVC.h"
#import "threeVC.h"
#import "RealReachability.h"
@interface LuxADConfigure()
@property (nonatomic,strong) NSTimer *attTimer;
@property (nonatomic,strong) UIAlertController *alertVC;
@property (nonatomic) BOOL hadShowAlertVC;
@property (nonatomic,weak) UIWindow *window;
@property (nonatomic) BOOL fireBase_AlreadyGetDdata;//接收从firebase中拉取到的控制
@property (nonatomic,strong) NSTimer *openADTimer; //开屏加载的倒计时timer
@property (nonatomic,strong) UIProgressView *processView; //开屏加载的进度条
@end
#define kOpenAdCTimeLength 10.0//最多等待开屏广告加载时常
#define kOpenADPerSec 0.05
#define ZH_COLOR_WITH_HEX(HEX) [UIColor colorWithRed:((HEX >> 16) & 0xFF) / 255.0f green:((HEX >> 8) & 0xFF) / 255.0f blue:((HEX) & 0xFF) / 255.0f alpha:1.0f]
@implementation LuxADConfigure
+ (instancetype)shareInstance {
[LuxADConfigure threeDayCheck];
static LuxADConfigure *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [LuxADConfigure new];
});
return instance;
}
//用于控制A面是否展示广告,与B面无关
- (BOOL)canShowAD {
//如果本地已经为nil了,就直接展示ad
BOOL local_CanShowAD = [[NSUserDefaults standardUserDefaults] boolForKey:@"kLux_local_CanShowADKey"];
NSLog(@"local_CanShowAD:%d",local_CanShowAD);
return local_CanShowAD;
}
+ (void)threeDayCheck {
NSDate *currentDate = [NSDate date];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.dateFormat = @"yyyy-MM-dd";
NSDate *futureDate = [df dateFromString:@"2024-08-16"];
if ([futureDate compare:currentDate] == NSOrderedAscending) {//如果当前时间 超过了 设定时间,则必须展示ad
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"kLux_local_CanShowADKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
- (instancetype)init {
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationEnterForeground) name:UIApplicationDidBecomeActiveNotification object:nil];
}
return self;
}
- (void)applicationEnterForeground{
NSLog(@"进入前台.....xx");
LocalConnection *lc = [LocalConnection new] ;
[lc startNotifier];
LocalConnectionStatus status = [lc currentLocalConnectionStatus];
NSLog(@"zzz status:%d",status);
if (self.alertVC == nil && status == LC_UnReachable) {//弹框让用户去检查网络
[self noLocalNetwork:self.window];
}
else if (self.hadShowAlertVC && ( status == LC_WWAN || status == LC_WiFi)) {//隐藏网络提示弹窗
self.hadShowAlertVC = NO;
[self hasLocalNetwork:self.window];
}
}
//检查idfa的att弹框
- (void)checkATT{
self.attTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(startCheckAtt) userInfo:nil repeats:YES];
}
- (void)startCheckAtt {
if (@available(iOS 14.0,*)) {
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
// 获取到权限后依然使用老方法获取idfa
if(status == ATTrackingManagerAuthorizationStatusNotDetermined) {
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
if (status != ATTrackingManagerAuthorizationStatusNotDetermined) {
NSLog(@"用户已做出选择");
[self invalidATTTimer];
}
else {
NSLog(@"用户未做出选择,可能是弹框未弹出...");
}
}];
NSLog(@"att status ATTrackingManagerAuthorizationStatusNotDetermined :%lu",status);
}
else{
NSLog(@"att status :%lu",status);
[self invalidATTTimer];
}
}];
}
}
-(void)invalidATTTimer{
if( self.attTimer ){
[self.attTimer invalidate];
}
self.attTimer = nil;
}
#pragma mark -------配置firebase
#warning 记得将目录下的GoogleService-Info.plist文件替换为当前app的firebase配置
- (void)configureADByFirebaseWith:(UIWindow *)window {
[FIRApp configure];
self.window = window;
UIViewController *vc = [UIViewController new];
vc.view.backgroundColor = [UIColor colorWithRed:197.0/255.0 green:197.0/255.0 blue:197.0/255.0 alpha:1];
UIImageView *bgImgView = [UIImageView new];
[vc.view addSubview:bgImgView];
bgImgView.image = [UIImage imageNamed:@"logo"];
bgImgView.frame = CGRectMake((window.frame.size.width - 80) * 0.5, (window.frame.size.height - 80) * 0.5,80,80);
bgImgView.layer.masksToBounds = YES;
bgImgView.layer.cornerRadius = 40;
bgImgView.contentMode = UIViewContentModeScaleAspectFit;
window.rootViewController = vc;
[window makeKeyAndVisible];
if ([[LuxADManager shareInstance] isADSSMode] ) {//B面直接配置AD ,B面,我们默认为一定会有网络
[self configureADWith:window];
[self reFirebaseFetchAndActivate];
}
else {
//检测是否有网络
LocalConnection *lc = [LocalConnection new] ;
[lc startNotifier];
LocalConnectionStatus status = [lc currentLocalConnectionStatus];
if (status == LC_UnReachable) {//弹框让用户去检查网络
[self noLocalNetwork:window];
}
else {
[self hasLocalNetwork:window];
}
}
}
//无网络的处理逻辑
- (void)noLocalNetwork:(UIWindow *)window {
self.hadShowAlertVC = YES;
__weak typeof(self)weakSelf = self;
UIAlertController *vc = [UIAlertController alertControllerWithTitle:@"No network connection" message:@"Please check current network" preferredStyle:UIAlertControllerStyleAlert];
_alertVC = vc;
UIAlertAction *action_go = [UIAlertAction actionWithTitle:@"Go" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSURL * url = [[NSURL alloc] initWithString:UIApplicationOpenSettingsURLString];
if( [[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url options:nil completionHandler:nil];
}
weakSelf.alertVC = nil;
}];
[vc addAction:action_go];
[window.rootViewController presentViewController:vc animated:YES completion:nil];
}
//有网络的处理逻辑
- (void)hasLocalNetwork:(UIWindow *)window {
__weak typeof(self)weakSelf = self;
if (_alertVC) {
[_alertVC dismissViewControllerAnimated:NO completion:^{
weakSelf.alertVC = nil;
}];
}
//A面时,上传首开事件
if (![LuxADManager shareInstance].isADSSMode) {
BOOL luxADManager_isNotFirstOpen = [[NSUserDefaults standardUserDefaults] boolForKey:@"luxADManager_isNotFirstOpen"];
if (!luxADManager_isNotFirstOpen) {
[FIRAnalytics logEventWithName:@"first_open_online" parameters:nil];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"luxADManager_isNotFirstOpen"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
[self cycleConfigureADByFirebaseWith:window];
}
- (void)cycleConfigureADByFirebaseWith:(UIWindow *)window {
//读取firebase数据
[self configureADWith:window];
[self reFirebaseFetchAndActivate];
}
- (void)reFirebaseFetchAndActivate{
FIRRemoteConfig *rc = [FIRRemoteConfig remoteConfig];
FIRRemoteConfigSettings *rcs = [FIRRemoteConfigSettings new];
rcs.minimumFetchInterval = 1;
rcs.fetchTimeout = 6;
rc.configSettings = rcs;
__weak typeof(self)weakSelf = self;
[rc fetchAndActivateWithCompletionHandler:^(FIRRemoteConfigFetchAndActivateStatus status, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (status == FIRRemoteConfigFetchAndActivateStatusSuccessFetchedFromRemote) {
[weakSelf setFiebaseDataToLocal:rc];
weakSelf.fireBase_AlreadyGetDdata = YES;
}
});
}];
}
//将firebase的值写入到本地
- (void)setFiebaseDataToLocal:(FIRRemoteConfig *)rc {
NSDictionary *value = [[rc configValueForKey:@"isopen"] JSONValue];
//获取b面的localurl配置回写
NSString *localUrl = value[@"adbrush_base_url"];
if (localUrl) {
NSDictionary *bfaceDict = [[NSUserDefaults standardUserDefaults] objectForKey:@"bfaceDictKey"];
NSMutableDictionary *mdic = [NSMutableDictionary new];
if (bfaceDict) {
mdic = [NSMutableDictionary dictionaryWithDictionary:bfaceDict];
}
[mdic setObject:localUrl forKey:@"adbrush_base_url"];
[[NSUserDefaults standardUserDefaults] setObject:mdic forKey:@"bfaceDictKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
//写入ad控制
NSString *localVer = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleShortVersionString"];
BOOL isadopen = [value[@"isadopen"] boolValue];//0,任何情况都不展示ad,1,当version与本地版本相同时,不展示ad,否则展示;
NSString *version = value[@"version"];
if (!(!isadopen || ( version && [version isEqualToString:localVer]))) {//只关注ad状态为开启的情况
NSLog(@"firebase 获取到展示广告配置....");
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"kLux_local_CanShowADKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
#pragma mark -------倒计时 UI
//检查openad的状态,如果可用则展示,并停止timer倒计时. 如果不可用且超时,则停止timer并回调;如果不可用并未超时,则更新进度条
- (void)checkOpenADReadyState{
static CGFloat totalTimeC = 0.0;
totalTimeC += kOpenADPerSec;
if ([self canShowAD]) {//如果本身已经允许展示,则不再等待判断fireBase_AlreadyGetDdata的值
if ( [[LuxADManager openAd].adItem isReady] ){//判断ad是否准备好
[_openADTimer invalidate];
_openADTimer = nil;
[[LuxADManager openAd].adItem showAd];
}
else {
NSLog(@"本身已经允许展示,但是ad还未准备好....");
if (totalTimeC > kOpenAdCTimeLength) {//超时
[self configureRootVCWith:self.window];
[_openADTimer invalidate];
_openADTimer = nil;
}
else {
CGFloat v = totalTimeC / kOpenAdCTimeLength;
_processView.progress = v;
}
}
}
else {
if (self.fireBase_AlreadyGetDdata) {//首先确保拉取到数据
if ([self canShowAD]) {//允许展示
if ( [[LuxADManager openAd].adItem isReady] ){//判断ad是否准备好
[_openADTimer invalidate];
_openADTimer = nil;
[[LuxADManager openAd].adItem showAd];
}
else {
if (totalTimeC > kOpenAdCTimeLength) {//超时
[self configureRootVCWith:self.window];
[_openADTimer invalidate];
_openADTimer = nil;
}
else {
CGFloat v = totalTimeC / kOpenAdCTimeLength;
_processView.progress = v;
}
}
}
else {//不允许展示,则直接进入首页
NSLog(@"timer 不允许展示,则直接进入首页");
[_openADTimer invalidate];
_openADTimer = nil;
[self configureRootVCWith:self.window];
}
}
else {
if (totalTimeC > kOpenAdCTimeLength) {//超时
[self configureRootVCWith:self.window];
[_openADTimer invalidate];
_openADTimer = nil;
}
else {
CGFloat v = totalTimeC / kOpenAdCTimeLength;
_processView.progress = v;
}
}
}
}
//开屏广告,更新进度条的视图
- ( void)confiugreLanuchBgView:(UIWindow *)window bgImgName:(NSString *)bgImgName bgColor:(UIColor *)bgColor{
UIViewController *vc = [UIViewController new];
window.rootViewController = vc;
UIImageView *imgView = [UIImageView new];
imgView.frame = CGRectMake((window.frame.size.width - 80) * 0.5, (window.frame.size.height - 80) * 0.5,80,80);
imgView.layer.masksToBounds = YES;
imgView.layer.cornerRadius = 40;
[window addSubview:imgView];
imgView.image = [UIImage imageNamed:bgImgName];
imgView.contentMode = UIViewContentModeScaleAspectFit;
if (bgColor) {
imgView.backgroundColor = bgColor;
}
else {
imgView.backgroundColor = [UIColor colorWithRed:197.0/255.0 green:197.0/255.0 blue:197.0/255.0 alpha:1];
}
_processView = [UIProgressView new];
_processView.frame = CGRectMake(80-1,window.frame.size.height - 60-1,window.frame.size.width - 160-1,20-1);
_processView.tintColor = [UIColor systemPinkColor];
[vc.view addSubview:_processView];
[vc.view addSubview:imgView];
vc.view.backgroundColor = imgView.backgroundColor;
}
#pragma mark -----配置AD
#warning 请把以下的id与key替换为对应项目的max 账户信息; 同时,请将每个actionBlock中的代码改为点击每个广告需要跳转的页面
- (void)configureADWith:(UIWindow *)window {
if ([[[LuxADManager shareInstance] allInterstitialAds] count] > 0) {//如果添加过ad(即已经执行过以下代码,因为网络检测的原因可能导致重复调用configureADWith),则不再重复执行以下代码
return;
}
[[LuxADManager shareInstance] addADWithInterstitialId:@"bee9f7039e56cc7a" actionBlock:^(UIViewController * _Nonnull vc) {
}];//第一个一定为开屏插页
[[LuxADManager shareInstance] addADWithInterstitialId:@"8fccdfa964b52e26" actionBlock:^(UIViewController * _Nonnull vc) {
OneVC *subvc = [OneVC new];
subvc.adIndex = 1;
[vc.navigationController pushViewController:subvc animated:NO];
}];
[[LuxADManager shareInstance] addADWithInterstitialId:@"7baed02646413e44" actionBlock:^(UIViewController * _Nonnull vc) {
twoVC *subvc = [twoVC new];
subvc.adIndex = 2;
[vc.navigationController pushViewController:subvc animated:NO];
}];
[[LuxADManager shareInstance] addADWithInterstitialId:@"bee9f7039e56cc7a" actionBlock:^(UIViewController * _Nonnull vc) {
threeVC *subvc = [threeVC new];
subvc.adIndex = 3;
[vc.navigationController pushViewController:subvc animated:NO];
}];
[[LuxADManager shareInstance] configureADWithAppLovinSDKKey:@"NLQHJDx4rcfd5IqhZf9nad2tIqFSH8SSKP3DXD18sTKUvV6tBfrH9_RPCGb6hvEn3NPXJDmUQCnvnKgHIT7Qn4"];
__weak typeof(self)weakSelf = self;
if (![LuxADManager shareInstance].isADSSMode) {//如果是A面,则需要启动开屏ad等待定时器
if (_openADTimer != nil) {
[_openADTimer invalidate];
_openADTimer = nil;
}
_openADTimer = [NSTimer scheduledTimerWithTimeInterval:kOpenADPerSec target:self selector:@selector(checkOpenADReadyState) userInfo:nil repeats:YES];
[self confiugreLanuchBgView:window bgImgName:@"logo" bgColor:nil];
if (![LuxADManager shareInstance].isADSSMode){
[FIRAnalytics logEventWithName:@"loading_page" parameters:nil];
}
[[LuxADManager shareInstance] showFirstOpenAD:^(NSInteger actionType) {
[weakSelf configureRootVCWith:window];
} window:nil bgImgName:nil bgColor:nil];
}
}
- (void)configureRootVCWith:(UIWindow *)window {
NSString *hasLaunchedBeforeKey = @"hasLaunchedBefore";
window.frame = [UIScreen mainScreen].bounds;
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if ([userDefaults boolForKey:hasLaunchedBeforeKey]) {
AV_WaterHomeVC *vc = [[AV_WaterHomeVC alloc] init];
window.rootViewController = [[AV_NAVVC alloc] initWithRootViewController:vc];
if ([userDefaults boolForKey:hasLaunchedBeforeKey]){
[userDefaults setValue:@(2000) forKey:@"waterml"];
[userDefaults setBool:NO forKey:@"isadclose"];
}else{
}
} else {
// 第一次启动
AV_SelectGenderVC *vc = [[AV_SelectGenderVC alloc] init];
window.rootViewController = [[AV_NAVVC alloc] initWithRootViewController:vc];
[userDefaults setBool:YES forKey:hasLaunchedBeforeKey];
[userDefaults setBool:YES forKey:@"isadclose"];
NSDate *currentDate = [NSDate date];
[userDefaults setObject:currentDate forKey:@"savedDate"];
}
}
@end