// // AppDelegate.swift // relax.offline.mp3.music // // Created by Mr.Zhou on 2024/5/22. // import UIKit import CoreData import AVFoundation import Alamofire import Tiercel import Firebase import GoogleMobileAds import FacebookCore @_exported import IQKeyboardManagerSwift @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? //当前页面状态 var showStatus:Bool! // 用来保存由系统提供的完成处理器 var backgroundSessionCompletionHandler: (() -> Void)? //退到后台的时间值 private var backgroundEntryTime:Date? //B面 private var positiceVC:MPPositive_TabBarController! func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { //请求通知权限 UNUserNotificationCenter.current() .requestAuthorization(options: [.alert, .sound, .badge]) { (accepted, error) in if !accepted { print("Users are not allowed to be notified of messages.") } } //广告默认ID coreAdMosIDs() ActiveDaysCalculation() //FireBase初始化 FirebaseApp.configure() //广告初始化 MP_AdMobManager.shared.start() //启动前销毁所有的下载任务 MP_DownloadManager.shared.cancelAllTasksIfNeeded() setAudioSupport() MP_NetWorkManager.shared.requestStatusToYouTube() IQKeyboardManager.shared.enable = true IQKeyboardManager.shared.shouldResignOnTouchOutside = true window = UIWindow(frame: UIScreen.main.bounds) window?.backgroundColor = .init(hex: "#161616") //关联faceBook ApplicationDelegate.shared.application(application,didFinishLaunchingWithOptions: launchOptions) //初始化三个控制器 positiceVC = MPPositive_TabBarController() switch_lunch() //执行用户启动事件日志 MP_AnalyticsManager.shared.user_launchAction() return true } func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:] ) -> Bool { ApplicationDelegate.shared.application(app, open: url, sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String, annotation: options[UIApplication.OpenURLOptionsKey.annotation]) } func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) { print("后台任务处理中-\(identifier)") if identifier == MP_DownloadManager.shared.session.identifier { MP_DownloadManager.shared.session.completionHandler = completionHandler } } //设置播放器会话状态 func setAudioSupport(){ //设置会话 let session = AVAudioSession.sharedInstance() do { //允许后台活跃,播放以及记录 try session.setCategory(.playAndRecord,mode: .default, options: [ .allowAirPlay, .allowBluetoothA2DP,.defaultToSpeaker]) //激活会话 try session.setActive(true) } catch { print("Failed to set type:\(error.localizedDescription)") } //响应后台控制 UIApplication.shared.beginReceivingRemoteControlEvents() } //存储修改值 func coreAdMosIDs() { if UserDefaults.standard.string(forKey: "OpenICEID") == nil { print("第一次启动,添加广告ID") //存入默认开屏冷启动广告ID UserDefaults.standard.set("ca-app-pub-1371732277241593/1926543650", forKey: "OpenICEID") } if UserDefaults.standard.string(forKey: "OpenHOSTID") == nil { //存入默认开屏热启动广告ID UserDefaults.standard.set("ca-app-pub-1371732277241593/3299335073", forKey: "OpenHOSTID") } if UserDefaults.standard.string(forKey: "SearchINSERTID") == nil { //存入默认搜索插页广告ID UserDefaults.standard.set("ca-app-pub-1371732277241593/8622500865", forKey: "SearchINSERTID") } if UserDefaults.standard.string(forKey: "SearchNATIVEID") == nil { //存入默认搜索原生广告ID UserDefaults.standard.set("ca-app-pub-1371732277241593/5674216970", forKey: "SearchNATIVEID") } if UserDefaults.standard.string(forKey: "PlayerINSERTID") == nil { //存入默认播放插页广告ID UserDefaults.standard.set("ca-app-pub-1371732277241593/4182802216", forKey: "PlayerINSERTID") } if UserDefaults.standard.string(forKey: "SwitchINSERTID") == nil { //存入默认切歌插页广告ID UserDefaults.standard.set("ca-app-pub-1371732277241593/8439981117", forKey: "SwitchINSERTID") } if UserDefaults.standard.string(forKey: "LoadINSERTID") == nil { //存入默认下载插页广告ID UserDefaults.standard.set("ca-app-pub-1371732277241593/3107763383", forKey: "LoadINSERTID") } if UserDefaults.standard.string(forKey: "LibraryINSERTID") == nil { //存入默认曲库插页ID UserDefaults.standard.set("ca-app-pub-1371732277241593/5298812459", forKey: "LibraryINSERTID") } if UserDefaults.standard.string(forKey: "LibraryNATIVEID") == nil { //存入默认曲库原生ID UserDefaults.standard.set("ca-app-pub-1371732277241593/4683255855", forKey: "LibraryNATIVEID") } if UserDefaults.standard.string(forKey: "GlobalINSERTID") == nil { //存入默认全局备用插页ID UserDefaults.standard.set("ca-app-pub-1371732277241593/9449223728", forKey: "GlobalINSERTID") } if UserDefaults.standard.string(forKey: "ClientVersion") == nil { UserDefaults.standard.set("1.20240618.01.00", forKey: "ClientVersion") } if UserDefaults.standard.string(forKey: "PlayerVersion") == nil { UserDefaults.standard.set("6.18.1", forKey: "PlayerVersion") } } //活跃天数计算 private func ActiveDaysCalculation() { //判断是否存在活跃天数组 guard var actives = UserDefaults.standard.object(forKey: "ActiveDays") as? [Date] else { //首次打开,没有存入数据 let now = Date().timeZone() UserDefaults.standard.setValue([now], forKey: "ActiveDays") return } //存在活跃天数,检索当前时间是否为新的活跃天 if let last = actives.last { //对比活跃天数组中最后一位与当前时间 let now = Date().timeZone() //确认现在时间值更大 if now > last { let calendar = Calendar.current let startDate = calendar.startOfDay(for: last) let endDate = calendar.startOfDay(for: now) let components = calendar.dateComponents([.day], from: startDate, to: endDate) //相差的天数 let days = components.day ?? 0 if days > 0 { //活跃的下一天 actives.append(now) UserDefaults.standard.setValue(actives, forKey: "ActiveDays") } } } } //MARK: - 页面跳转 ///跳转启动页 func switch_lunch() { let lunchVC = MP_LunchViewController() //动画设置 let transtition = CATransition() transtition.duration = 0.8 transtition.timingFunction = .init(name: .easeOut)//外层模糊化 window?.layer.add(transtition, forKey: "lunch.easeOut") window?.rootViewController = lunchVC window?.makeKeyAndVisible() } ///跳转A面 func switch_aSide() { guard showStatus != false else { return } let tabBarVC = MPSideA_TabBarController() //动画设置 let transtition = CATransition() transtition.duration = 0.8 transtition.timingFunction = .init(name: .easeOut)//外层模糊化 window?.layer.add(transtition, forKey: "aSide.easeOut") window?.rootViewController = tabBarVC window?.makeKeyAndVisible() showStatus = false } //跳转b面 func switch_positive() { guard showStatus != true else { return } //销毁A面所有内容 MPSideA_MediaCenterManager.shared.destroySideA() MPSideA_VolumeManager.shared.destroySideA() //动画设置 let transtition = CATransition() transtition.duration = 0.8 transtition.timingFunction = .init(name: .easeOut)//外层模糊化 window?.layer.add(transtition, forKey: "positive.easeOut") window?.rootViewController = positiceVC window?.makeKeyAndVisible() showStatus = true } //MARK: - 前后台检索设置 //退往后台 func applicationDidEnterBackground(_ application: UIApplication) { //更新当前后台时间节点 backgroundEntryTime = Date() } //将要进入前台 func applicationWillEnterForeground(_ application: UIApplication) { } //进入前台 func applicationDidBecomeActive(_ application: UIApplication) { guard let backDate = backgroundEntryTime else { return } backgroundEntryTime = nil //当前时间值 let currentDate = Date() //算出与后台时间节点的差值 let duration = currentDate.timeIntervalSince(backDate) //获取插页间隔时长 let times = MP_AdMobManager.shared.getOpenAppDuration() if duration >= times { MP_AdMobManager.shared.showOpenAdIfAvailable(.HOST, completion: nil) //超过间隔时长,进行热启动广告展示 print("返回前台,并展示了热启动广告") }else { //未超过,无事发生 print("返回前台") } } // MARK: - Core Data stack lazy var persistentContainer: NSPersistentContainer = { /* The persistent container for the application. This implementation creates and returns a container, having loaded the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail. */ let container = NSPersistentContainer(name: "relax.offline.mp3") container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error as NSError? { // Replace this implementation with code to handle the error appropriately. // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. /* Typical reasons for an error here include: * The parent directory does not exist, cannot be created, or disallows writing. * The persistent store is not accessible, due to permissions or data protection when the device is locked. * The device is out of space. * The store could not be migrated to the current model version. Check the error message to determine what the actual problem was. */ fatalError("Unresolved error \(error), \(error.userInfo)") } }) return container }() // MARK: - Core Data Saving support func saveContext () { let context = persistentContainer.viewContext if context.hasChanges { do { try context.save() } catch { // Replace this implementation with code to handle the error appropriately. // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. let nserror = error as NSError fatalError("Unresolved error \(nserror), \(nserror.userInfo)") } } } } ///访问appDelegate let accessAppdelegate = ( UIApplication.shared.delegate as! AppDelegate)