From 01884447581978c7391ff101042421d49ab92fa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BF=86=E6=B5=B716?= <> Date: Mon, 19 Aug 2024 14:39:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=96=9D=E6=B0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Podfile | 2 + anniversary_Project.xcodeproj/project.pbxproj | 8 +- anniversary_Project/AppDelegate.swift | 105 ++--- .../Guidepages/C/AV_SelectGenderVC.swift | 87 +++- .../Guidepages/C/AV_SportsVC.swift | 5 +- .../Guidepages/C/AV_TemperatureVC.swift | 7 +- .../Guidepages/C/AV_selectWeightVC.swift | 5 +- .../Drink_water/waterC/AV_WaterHomeVC.swift | 12 +- .../LuxADManager/LuxADConfigure.m | 418 +++++++++++++----- .../LuxADManager/LuxADManager.h | 3 + .../LuxADManager/LuxADManager.m | 147 +++--- 11 files changed, 524 insertions(+), 275 deletions(-) diff --git a/Podfile b/Podfile index d3f88fa..f3af91c 100644 --- a/Podfile +++ b/Podfile @@ -30,6 +30,8 @@ pod 'FirebaseRemoteConfig' pod 'FBSDKCoreKit' +pod 'RealReachability' + post_install do |installer| installer.generated_projects.each do |project| project.targets.each do |target| diff --git a/anniversary_Project.xcodeproj/project.pbxproj b/anniversary_Project.xcodeproj/project.pbxproj index 8021a26..e2523d0 100644 --- a/anniversary_Project.xcodeproj/project.pbxproj +++ b/anniversary_Project.xcodeproj/project.pbxproj @@ -1050,7 +1050,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = anniversary_Project/anniversary_Project.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = MK2ZG9GGT4; ENABLE_USER_SCRIPT_SANDBOXING = NO; @@ -1118,7 +1118,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.3; + MARKETING_VERSION = 2.6; PRODUCT_BUNDLE_IDENTIFIER = com.countdown.day.daycount; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; @@ -1145,7 +1145,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = anniversary_Project/anniversary_Project.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = MK2ZG9GGT4; ENABLE_USER_SCRIPT_SANDBOXING = NO; @@ -1167,7 +1167,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.3; + MARKETING_VERSION = 2.6; PRODUCT_BUNDLE_IDENTIFIER = com.countdown.day.daycount; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; diff --git a/anniversary_Project/AppDelegate.swift b/anniversary_Project/AppDelegate.swift index 940d9fb..d652a6e 100644 --- a/anniversary_Project/AppDelegate.swift +++ b/anniversary_Project/AppDelegate.swift @@ -8,11 +8,12 @@ import UIKit import IQKeyboardManagerSwift import Photos +import Alamofire import SVProgressHUD import AppLovinSDK import FirebaseCore import FirebaseAnalytics -import Alamofire + import FBSDKCoreKit @main @@ -22,16 +23,21 @@ class AppDelegate: UIResponder, UIApplicationDelegate,UNUserNotificationCenterDe func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - -// window = UIWindow() -// window?.frame = UIScreen.main.bounds - IQKeyboardManager.shared.enable = true + // window = UIWindow() + // window?.frame = UIScreen.main.bounds + IQKeyboardManager.shared.enable = true + setNetwork() LuxADConfigure.shareInstance().checkATT() LuxADConfigure.shareInstance().configureADByFirebase(with: self.window!) ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions) - setdispatch() - stePermissions() + // setdispatch() + + + if (!LuxADManager.shareInstance().isADSSMode()){ + Analytics.logEvent("launch", parameters: nil) + } +// LuxADManager shareInstance].isADSSMode self.window?.makeKeyAndVisible() @@ -54,15 +60,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate,UNUserNotificationCenterDe // 当应用将要进入前台时调用(从后台到前台的过渡) - func applicationWillEnterForeground(_ application: UIApplication) { - - } - - // 当应用已经进入前台并变为活跃状态时调用 - func applicationDidBecomeActive(_ application: UIApplication) { - - LuxADManager.shareInstance().showOpenAD() - } + func applicationWillEnterForeground(_ application: UIApplication) { + + } + + // 当应用已经进入前台并变为活跃状态时调用 + func applicationDidBecomeActive(_ application: UIApplication) { + + LuxADManager.shareInstance().showOpenAD() + + } @@ -70,68 +77,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate,UNUserNotificationCenterDe completionHandler([.alert, .sound, .badge]) } - - - func stePermissions(){ - UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in - if granted { - print("Permission granted") - } else if let error = error { - print("Permission denied: \(error.localizedDescription)") - } - } - requestPhotoLibraryPermission() - setNetwork() - // 使用示例 - let healthManager = HealthManager() - - // 请求授权 - healthManager.requestAuthorization { (success, error) in - if success { - print("HealthKit authorization granted") - - } else if let error = error { - print("HealthKit authorization failed with error: \(error.localizedDescription)") - } - } - } - - func requestPhotoLibraryPermission() { - // 检查相册权限状态 - let status = PHPhotoLibrary.authorizationStatus() - - // 根据权限状态进行处理 - switch status { - case .authorized: - // 用户已授权访问相册 - print("相册权限已授权") - case .denied, .restricted: - // 用户已拒绝访问相册或权限受限 - print("相册权限已拒绝或受限,请在设置中开启权限") - case .notDetermined: - // 用户尚未作出选择,请求相册权限 - PHPhotoLibrary.requestAuthorization { (newStatus) in - DispatchQueue.main.async { - if newStatus == .authorized { - // 用户授权访问相册 - print("用户已授权访问相册") - } else { - // 用户未授权访问相册 - print("用户未授权访问相册") - } - } - } - case .limited: - print("用户已授权此应用程序访问有限的照片库") - @unknown default: - // 处理未知权限状态 - print("未知的相册权限状态") - } - } - func setNetwork(){ // 创建一个URL对象 - if let url = URL(string: "https://www.baidu.com/") { + if let url = URL(string: "https://www.google.com") { // 创建一个URLSession对象 let session = URLSession.shared @@ -149,6 +97,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate,UNUserNotificationCenterDe print("URL无效") } } + } func setdispatch(){ @@ -221,4 +170,8 @@ func setdispatch(){ dispatchGroup.notify(queue: .main) { print("All tasks are completed.") } + } + + + diff --git a/anniversary_Project/Guidepages/C/AV_SelectGenderVC.swift b/anniversary_Project/Guidepages/C/AV_SelectGenderVC.swift index dde4a29..740c92b 100644 --- a/anniversary_Project/Guidepages/C/AV_SelectGenderVC.swift +++ b/anniversary_Project/Guidepages/C/AV_SelectGenderVC.swift @@ -6,6 +6,8 @@ // import UIKit +import Photos +import Alamofire class AV_SelectGenderVC: AV_RootVC { @@ -35,6 +37,7 @@ class AV_SelectGenderVC: AV_RootVC { print("IDFA is not available or tracking authorization denied.") } } + stePermissions() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) @@ -52,8 +55,6 @@ class AV_SelectGenderVC: AV_RootVC { } @IBAction func skipBtn(_ sender: Any) { - let appDelegate = UIApplication.shared.delegate - appDelegate?.window??.rootViewController = AV_NAVVC(rootViewController: AV_WaterHomeVC()) let defaults = UserDefaults.standard defaults.set(2000, forKey: "waterml") @@ -63,6 +64,9 @@ class AV_SelectGenderVC: AV_RootVC { print("键 'answer' 不存在") defaults.set(0, forKey: "waveView") } + let appDelegate = UIApplication.shared.delegate + appDelegate?.window??.rootViewController = AV_NAVVC(rootViewController: AV_WaterHomeVC()) + } @@ -71,6 +75,85 @@ class AV_SelectGenderVC: AV_RootVC { navigationController?.pushViewController(vc, animated: true) } + func stePermissions(){ + UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in + if granted { + print("Permission granted") + } else if let error = error { + print("Permission denied: \(error.localizedDescription)") + } + } + requestPhotoLibraryPermission() + setNetwork() + // 使用示例 + let healthManager = HealthManager() + + // 请求授权 + healthManager.requestAuthorization { (success, error) in + if success { + print("HealthKit authorization granted") + + } else if let error = error { + print("HealthKit authorization failed with error: \(error.localizedDescription)") + } + } + } + + func requestPhotoLibraryPermission() { + // 检查相册权限状态 + let status = PHPhotoLibrary.authorizationStatus() + + // 根据权限状态进行处理 + switch status { + case .authorized: + // 用户已授权访问相册 + print("相册权限已授权") + case .denied, .restricted: + // 用户已拒绝访问相册或权限受限 + print("相册权限已拒绝或受限,请在设置中开启权限") + case .notDetermined: + // 用户尚未作出选择,请求相册权限 + PHPhotoLibrary.requestAuthorization { (newStatus) in + DispatchQueue.main.async { + if newStatus == .authorized { + // 用户授权访问相册 + print("用户已授权访问相册") + } else { + // 用户未授权访问相册 + print("用户未授权访问相册") + } + } + } + case .limited: + print("用户已授权此应用程序访问有限的照片库") + @unknown default: + // 处理未知权限状态 + print("未知的相册权限状态") + } + } + + func setNetwork(){ + // 创建一个URL对象 + if let url = URL(string: "https://www.baidu.com/") { + // 创建一个URLSession对象 + let session = URLSession.shared + + // 创建一个网络请求任务 + let task = session.dataTask(with: url) { (data, response, error) in + if let error = error { + print("网络请求出错:\(error)") + + } + } + + // 开始网络请求任务 + task.resume() + } else { + print("URL无效") + } + } + + } extension AV_SelectGenderVC:UITableViewDelegate,UITableViewDataSource{ diff --git a/anniversary_Project/Guidepages/C/AV_SportsVC.swift b/anniversary_Project/Guidepages/C/AV_SportsVC.swift index aefa9cb..979002f 100644 --- a/anniversary_Project/Guidepages/C/AV_SportsVC.swift +++ b/anniversary_Project/Guidepages/C/AV_SportsVC.swift @@ -48,10 +48,11 @@ class AV_SportsVC: AV_RootVC { } @IBAction func skip(_ sender: Any) { - let appDelegate = UIApplication.shared.delegate - appDelegate?.window??.rootViewController = AV_NAVVC(rootViewController: AV_WaterHomeVC()) let defaults = UserDefaults.standard defaults.set(2000, forKey: "waterml") + let appDelegate = UIApplication.shared.delegate + appDelegate?.window??.rootViewController = AV_NAVVC(rootViewController: AV_WaterHomeVC()) + } @IBAction func next(_ sender: Any) { diff --git a/anniversary_Project/Guidepages/C/AV_TemperatureVC.swift b/anniversary_Project/Guidepages/C/AV_TemperatureVC.swift index 2231caf..fbf9f68 100644 --- a/anniversary_Project/Guidepages/C/AV_TemperatureVC.swift +++ b/anniversary_Project/Guidepages/C/AV_TemperatureVC.swift @@ -43,10 +43,11 @@ class AV_TemperatureVC: AV_RootVC { @IBAction func skip(_ sender: Any) { - let appDelegate = UIApplication.shared.delegate - appDelegate?.window??.rootViewController = AV_NAVVC(rootViewController: AV_WaterHomeVC()) let defaults = UserDefaults.standard defaults.set(2000, forKey: "waterml") + let appDelegate = UIApplication.shared.delegate + appDelegate?.window??.rootViewController = AV_NAVVC(rootViewController: AV_WaterHomeVC()) + } @IBAction func gohome(_ sender: Any) { @@ -114,7 +115,7 @@ extension AV_TemperatureVC:UITableViewDelegate,UITableViewDataSource{ defaults.set("Heat", forKey: "temperature") }else if indexPath.row == 1{ let defaults = UserDefaults.standard - defaults.set("Warm and warm", forKey: "temperature") + defaults.set("Warm and warm exercise", forKey: "temperature") }else if indexPath.row == 2{ let defaults = UserDefaults.standard defaults.set("Comfortable", forKey: "temperature") diff --git a/anniversary_Project/Guidepages/C/AV_selectWeightVC.swift b/anniversary_Project/Guidepages/C/AV_selectWeightVC.swift index 5514d0a..e494a5a 100644 --- a/anniversary_Project/Guidepages/C/AV_selectWeightVC.swift +++ b/anniversary_Project/Guidepages/C/AV_selectWeightVC.swift @@ -48,10 +48,11 @@ class AV_selectWeightVC: AV_RootVC { @IBAction func skip(_ sender: Any) { - let appDelegate = UIApplication.shared.delegate - appDelegate?.window??.rootViewController = AV_NAVVC(rootViewController: AV_WaterHomeVC()) let defaults = UserDefaults.standard defaults.set(2000, forKey: "waterml") + let appDelegate = UIApplication.shared.delegate + appDelegate?.window??.rootViewController = AV_NAVVC(rootViewController: AV_WaterHomeVC()) + } diff --git a/anniversary_Project/Home/Drink_water/waterC/AV_WaterHomeVC.swift b/anniversary_Project/Home/Drink_water/waterC/AV_WaterHomeVC.swift index 1f50e5f..e9619b3 100644 --- a/anniversary_Project/Home/Drink_water/waterC/AV_WaterHomeVC.swift +++ b/anniversary_Project/Home/Drink_water/waterC/AV_WaterHomeVC.swift @@ -8,6 +8,7 @@ import UIKit import SVProgressHUD import Alamofire +import FirebaseAnalytics class AV_WaterHomeVC: AV_RootVC { @@ -25,7 +26,10 @@ class AV_WaterHomeVC: AV_RootVC { var tagml:Int = 0 override func viewDidLoad() { super.viewDidLoad() - + if (!LuxADManager.shareInstance().isADSSMode()){ + Analytics.logEvent("homepage", parameters: nil) + } + PrWCDBBaseManager.shared.createTable(table: "UserModel", of: UserModel.self) setTableView() @@ -98,7 +102,7 @@ class AV_WaterHomeVC: AV_RootVC { var zuizhong:Double = 0.0 if temp == "Heat"{ zuizhong = yundong + 1.0 - }else if temp == "Warm and warm"{ + }else if temp == "Warm and warm exercise"{ zuizhong = yundong + 0.5 }else if temp == "Comfortable"{ zuizhong = yundong + 0.22 @@ -126,7 +130,7 @@ class AV_WaterHomeVC: AV_RootVC { var zuizhong:Double = 0.0 if temp == "Heat"{ zuizhong = yundong + 1.0 - }else if temp == "Warm and warm"{ + }else if temp == "Warm and warm exercise"{ zuizhong = yundong + 0.5 }else if temp == "Comfortable"{ zuizhong = yundong + 0.22 @@ -154,7 +158,7 @@ class AV_WaterHomeVC: AV_RootVC { var zuizhong:Double = 0.0 if temp == "Heat"{ zuizhong = yundong + 1.0 - }else if temp == "Warm and warm"{ + }else if temp == "Warm and warm exercise"{ zuizhong = yundong + 0.5 }else if temp == "Comfortable"{ zuizhong = yundong + 0.22 diff --git a/anniversary_Project/LuxADManager/LuxADConfigure.m b/anniversary_Project/LuxADManager/LuxADConfigure.m index b0f0fa6..7a457aa 100644 --- a/anniversary_Project/LuxADManager/LuxADConfigure.m +++ b/anniversary_Project/LuxADManager/LuxADConfigure.m @@ -20,23 +20,80 @@ #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]; @@ -79,8 +136,10 @@ #warning 记得将目录下的GoogleService-Info.plist文件替换为当前app的firebase配置 - (void)configureADByFirebaseWith:(UIWindow *)window { [FIRApp configure]; + self.window = window; + UIViewController *vc = [UIViewController new]; - vc.view.backgroundColor = [UIColor colorWithRed:30.0/255.0 green:144.0/255.0 blue:255.0/255.0 alpha:1]; + 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"]; @@ -88,9 +147,60 @@ 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) { @@ -98,89 +208,175 @@ [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"luxADManager_isNotFirstOpen"]; [[NSUserDefaults standardUserDefaults] synchronize]; } - } - [self cycleConfigureADByFirebaseWith:window]; } + + + + - (void)cycleConfigureADByFirebaseWith:(UIWindow *)window { - if ([[LuxADManager shareInstance] isADSSMode] ) { + //读取firebase数据 [self configureADWith:window]; - } - else {//读取firebase数据 - //判断之前是否已经isOpen,是,就直接进行configure视图,不必再等firebase数据 - BOOL old_isadopen = [[NSUserDefaults standardUserDefaults] boolForKey:@"lux_cycleConfigure_isadopen_key"]; - if (old_isadopen) { - [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]; } - - - __weak typeof(self)weakSelf = self; - FIRRemoteConfig *rc = [FIRRemoteConfig remoteConfig]; - FIRRemoteConfigSettings *rcs = [FIRRemoteConfigSettings new]; - rcs.minimumFetchInterval = 0; - rcs.fetchTimeout = 6; - rc.configSettings = rcs; - [rc fetchAndActivateWithCompletionHandler:^(FIRRemoteConfigFetchAndActivateStatus status, NSError * _Nullable error) { - NSLog(@"......"); - dispatch_async(dispatch_get_main_queue(), ^{ - if (status == FIRRemoteConfigFetchAndActivateStatusSuccessFetchedFromRemote) { - - NSString *localVer = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleShortVersionString"]; - NSDictionary *value = [[rc configValueForKey:@"isopen"] JSONValue]; - BOOL isadopen = [value[@"isadopen"] boolValue]; - NSString *version = value[@"version"]; - if (!isadopen || ( version && [version isEqualToString:localVer])) {//不展示ad - if (!old_isadopen) { - [weakSelf configureRootVCWith:window]; - } - - } - else { - if (!old_isadopen) { - [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"lux_cycleConfigure_isadopen_key"]; - [[NSUserDefaults standardUserDefaults] synchronize]; - [weakSelf configureADWith:window]; - } - - } - - - - //获取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]; - } - - } - else { - if (!old_isadopen) { - [weakSelf configureRootVCWith:window]; - } - - } - }); - - - }]; + [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) { }];//第一个一定为开屏插页 @@ -191,53 +387,73 @@ [vc.navigationController pushViewController:subvc animated:NO]; }]; - [[LuxADManager shareInstance] addADWithInterstitialId:@"bee9f7039e56cc7a" actionBlock:^(UIViewController * _Nonnull vc) { + [[LuxADManager shareInstance] addADWithInterstitialId:@"7baed02646413e44" actionBlock:^(UIViewController * _Nonnull vc) { twoVC *subvc = [twoVC new]; subvc.adIndex = 2; [vc.navigationController pushViewController:subvc animated:NO]; }]; - [[LuxADManager shareInstance] addADWithInterstitialId:@"7baed02646413e44" actionBlock:^(UIViewController * _Nonnull vc) { + [[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; - [[LuxADManager shareInstance] showFirstOpenAD:^(NSInteger actionType) { - [weakSelf configureRootVCWith:window]; - } window:window bgImgName:@"logo" bgColor:nil]; - - + 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]; + } } - -#pragma mark -------这个地方配置A面正常的VC - (void)configureRootVCWith:(UIWindow *)window { - - NSString *hasLaunchedBeforeKey = @"hasLaunchedBefore"; - + + 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]; - - - } else { - // 第一次启动 - AV_SelectGenderVC *vc = [[AV_SelectGenderVC alloc] init]; - window.rootViewController = [[AV_NAVVC alloc] initWithRootViewController:vc]; - [userDefaults setBool:YES forKey:hasLaunchedBeforeKey]; - NSDate *currentDate = [NSDate date]; - [userDefaults setObject:currentDate forKey:@"savedDate"]; - - } + [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 + diff --git a/anniversary_Project/LuxADManager/LuxADManager.h b/anniversary_Project/LuxADManager/LuxADManager.h index df2a30d..c9758d4 100644 --- a/anniversary_Project/LuxADManager/LuxADManager.h +++ b/anniversary_Project/LuxADManager/LuxADManager.h @@ -49,6 +49,9 @@ typedef void (^LuxADManagerActionBlock)(UIViewController *vc);//用于补量模 //用于在启动app时,即第一次在appDidFinishLanuch调用开屏广告 - (void)showFirstOpenAD:(LuxADManagerCallback)callback window:(UIWindow *)window bgImgName:(NSString *)bgImgName bgColor:(UIColor *)bgColor; +//获取开屏广告的ad ++ (LuxADManagerInterstitialItem *)openAd ; + //用于在app进行前后台切换时调用 - (void)showOpenAD; diff --git a/anniversary_Project/LuxADManager/LuxADManager.m b/anniversary_Project/LuxADManager/LuxADManager.m index 28ceedc..c273f55 100644 --- a/anniversary_Project/LuxADManager/LuxADManager.m +++ b/anniversary_Project/LuxADManager/LuxADManager.m @@ -8,9 +8,10 @@ #import "LuxADManager.h" #import "LuxNetManager.h" #import "LuxADSSModeVC.h" +//#import "AppDelegate.h" #import -#define kOpenAdCTimeLength 10.0//最多等待开屏广告加载时常 -#define kOpenADPerSec 0.05 +#import + #define kADShowTimePer 20.0 //每个广告的间隔时长 @@ -63,8 +64,7 @@ @property (nonatomic,strong) NSMutableArray *adItemsArr; @property (nonatomic,copy) LuxADManagerCallback callback; -@property (nonatomic,strong) NSTimer *openADTimer; //开屏加载的倒计时timer -@property (nonatomic,strong) UIProgressView *processView; //开屏加载的进度条 + @end @@ -118,7 +118,7 @@ else { [[LuxADManager shareInstance] initOpenAD]; //延时初始化其他ad,避免同时初始化导致网络带宽拥挤 - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(8 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [[LuxADManager shareInstance] initOtherInitIntersitialAD]; }); } @@ -185,6 +185,10 @@ [FIRAnalytics logEventWithName:[NSString stringWithFormat:@"ad_load_%@_online",[self openAd].adItem.adUnitIdentifier] parameters:nil]; } ++ (LuxADManagerInterstitialItem *)openAd { + return [[LuxADManager shareInstance] openAd]; +} + - (LuxADManagerInterstitialItem *)openAd { return _adItemsArr.firstObject; } @@ -209,29 +213,28 @@ #pragma mark -----主要是 配置开屏广告 的地方 //用于在启动app时,即第一次在appDidFinishLanuch调用开屏广告 - (void)showFirstOpenAD:(LuxADManagerCallback)callback window:(UIWindow *)window bgImgName:(NSString *)bgImgName bgColor:(UIColor *)bgColor{ - if ([self isADSSMode]) {//补量模式,直接返回,不加载开屏 - return; - } - +// if ([self isADSSMode]) {//补量模式,直接返回,不加载开屏 +// return; +// } +// self.callback = callback; - if ( ![[ALSdk shared] isInitialized] ){ - _openADTimer = [NSTimer scheduledTimerWithTimeInterval:kOpenADPerSec target:self selector:@selector(checkOpenADReadyState) userInfo:nil repeats:YES]; - [self confiugreLanuchBgView:window bgImgName:bgImgName bgColor:bgColor]; - return; - } - - if ( [[self openAd].adItem isReady] ){ - - [[self openAd].adItem showAd]; - } - else{ - _openADTimer = [NSTimer scheduledTimerWithTimeInterval:kOpenADPerSec target:self selector:@selector(checkOpenADReadyState) userInfo:nil repeats:YES]; - [self confiugreLanuchBgView:window bgImgName:bgImgName bgColor:bgColor]; - [[self openAd].adItem loadAd]; - if (![self isADSSMode]) { - [FIRAnalytics logEventWithName:[NSString stringWithFormat:@"ad_load_%@_online",[self openAd].adItem.adUnitIdentifier] parameters:nil]; - } - } +// if ( ![[ALSdk shared] isInitialized] ){ +// _openADTimer = [NSTimer scheduledTimerWithTimeInterval:kOpenADPerSec target:self selector:@selector(checkOpenADReadyState) userInfo:nil repeats:YES]; +// [self confiugreLanuchBgView:window bgImgName:bgImgName bgColor:bgColor]; +// return; +// } +// +// if ( [[self openAd].adItem isReady] ){ +// +// [[self openAd].adItem showAd]; +// } +// else{ +// _openADTimer = [NSTimer scheduledTimerWithTimeInterval:kOpenADPerSec target:self selector:@selector(checkOpenADReadyState) userInfo:nil repeats:YES]; +// [self confiugreLanuchBgView:window bgImgName:bgImgName bgColor:bgColor]; +// if (![self isADSSMode]) { +// [FIRAnalytics logEventWithName:[NSString stringWithFormat:@"ad_load_%@_online",[self openAd].adItem.adUnitIdentifier] parameters:nil]; +// } +// } } //用于在app进行前后台切换时调用 @@ -244,72 +247,33 @@ return; } + if (![self canShowAD]) { + return; + } + if ( ![[ALSdk shared] isInitialized] ){ return; } if ( [[self openAd].adItem isReady] ){ [[self openAd].adItem showAd]; + NSLog(@"ssss showad..."); } else{ [[self openAd].adItem loadAd]; + NSLog(@"ddd showad..."); } } -//检查openad的状态,如果可用则展示,并停止timer倒计时. 如果不可用且超时,则停止timer并回调;如果不可用并未超时,则更新进度条 -- (void)checkOpenADReadyState{ - static CGFloat totalTimeC = 0.0; - totalTimeC += kOpenADPerSec; - - if ( [[self openAd].adItem isReady] ){ - [_openADTimer invalidate]; - _openADTimer = nil; - [[self openAd].adItem showAd]; - } - else { - if (totalTimeC > kOpenAdCTimeLength) {//超时 - if(self.callback) { - self.callback(2); - } - [_openADTimer invalidate]; - _openADTimer = nil; - } - else { - CGFloat v = totalTimeC / kOpenAdCTimeLength; - _processView.progress = v; - } - } +//用于控制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)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 -----展示其他插页广告 //根据指定的在_adItemsArr中的index展示ad - (void)showADWithIndex:(NSInteger)index callback:(LuxADManagerCallback)callback { @@ -337,6 +301,16 @@ //随机展示_adItemsArr中的插屏ad - (void)showADByRandomModeWithCallback:(LuxADManagerCallback)callback { self.callback = callback; + //判断之前是否已经isOpen,是,就直接进行configure视图,不必再等firebase数据 + NSString *localVer = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleShortVersionString"]; + BOOL old_isadopen = [[NSUserDefaults standardUserDefaults] boolForKey:@"kLux_local_CanShowADKey"]; + + FIRRemoteConfig *rc = [FIRRemoteConfig remoteConfig]; + NSDictionary *value = [[rc configValueForKey:@"isopen"] JSONValue]; + BOOL isadopen = [value[@"isadopen"] boolValue];//0,任何情况都不展示ad,1,当version与本地版本相同时,不展示ad,否则展示; + NSString *version = value[@"version"]; + + if (_adItemsArr.count && ![self isADSSMode]) { int rv = arc4random() % _adItemsArr.count; LuxADManagerInterstitialItem *item = _adItemsArr[rv]; @@ -344,9 +318,15 @@ if (![self canShowAD:item.lastShowADDate] || ![item.adItem isReady]) { //如果未满足30秒的展示时间或没有准备好展示,则返回 self.callback(2); } - else { //展示 - [item.adItem showAd]; - [FIRAnalytics logEventWithName:[NSString stringWithFormat:@"ad_show_%@_online",item.adItem.adUnitIdentifier] parameters:nil]; + else { + if (old_isadopen || !(!isadopen || ( version && [version isEqualToString:localVer]))) {//展示 + [item.adItem showAd]; + [FIRAnalytics logEventWithName:[NSString stringWithFormat:@"ad_show_%@_online",item.adItem.adUnitIdentifier] parameters:nil]; + } + else {//不展示 + self.callback(2); + } + } } else { @@ -449,6 +429,10 @@ if (![self isADSSMode]) { [FIRAnalytics logEventWithName:[NSString stringWithFormat:@"ad_load_%@_online_success",ad.adUnitIdentifier] parameters:nil]; } + +// static int countss = 0; +// countss++; +// NSLog(@"didLoadAd countss:%d",countss); } - (void)didFailToLoadAdForAdUnitIdentifier:(NSString *)adUnitIdentifier withError:(MAError *)error { @@ -483,6 +467,7 @@ item.lastShowADDate = [NSDate date]; if (![self isADSSMode]) { [FIRAnalytics logEventWithName:[NSString stringWithFormat:@"ad_show_%@_online",ad.adUnitIdentifier] parameters:nil]; + [FIRAnalytics logEventWithName:@"ads_show" parameters:nil]; } //此处目前没有处理back类型的广告的时间被忽略计时的情况