diff --git a/relax.offline.mp3.music.xcworkspace/xcuserdata/zhou.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/relax.offline.mp3.music.xcworkspace/xcuserdata/zhou.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index ae8d276..27c3c46 100644 --- a/relax.offline.mp3.music.xcworkspace/xcuserdata/zhou.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/relax.offline.mp3.music.xcworkspace/xcuserdata/zhou.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -3,22 +3,4 @@ uuid = "B2D42C7E-B789-40F0-8339-B70A223A3889" type = "0" version = "2.0"> - - - - - - diff --git a/relax.offline.mp3.music/MP/Common/Macro(宏定义与全局量)/Macro.swift b/relax.offline.mp3.music/MP/Common/Macro(宏定义与全局量)/Macro.swift index ded4568..ca7ad56 100644 --- a/relax.offline.mp3.music/MP/Common/Macro(宏定义与全局量)/Macro.swift +++ b/relax.offline.mp3.music/MP/Common/Macro(宏定义与全局量)/Macro.swift @@ -79,6 +79,10 @@ let serviceUrl:URL = .init(string: "https://musiclax.mystrikingly.com/terms")! //MARK: - 全局变量与方法 //存储默认配置值 func coreDefaultValues() { + if UserDefaults.standard.string(forKey: "OpenICEID") != nil { + print("清理旧数据") + UserDefaults.standard.removeObject(forKey: "OpenICEID") + } if UserDefaults.standard.object(forKey: "OpenICEID") == nil { print("第一次启动,添加广告ID") if let array = coreAdModelforJson([.init(level: 3, identifier: "ca-app-pub-1371732277241593/2126815630", ad: "AdMob", type: .Insert), @@ -89,6 +93,9 @@ func coreDefaultValues() { UserDefaults.standard.set(array, forKey: "OpenICEID") } } + if UserDefaults.standard.string(forKey: "OpenHOSTID") != nil { + UserDefaults.standard.removeObject(forKey: "OpenHOSTID") + } if UserDefaults.standard.object(forKey: "OpenHOSTID") == nil { if let array = coreAdModelforJson([.init(level: 3, identifier: "ca-app-pub-1371732277241593/9262752398", ad: "AdMob", type: .Insert), .init(level: 2, identifier: "ca-app-pub-1371732277241593/6536516707", ad: "AdMob", type: .Open), @@ -98,6 +105,9 @@ func coreDefaultValues() { UserDefaults.standard.set(array, forKey: "OpenHOSTID") } } + if UserDefaults.standard.string(forKey: "SearchINSERTID") != nil { + UserDefaults.standard.removeObject(forKey: "SearchINSERTID") + } if UserDefaults.standard.object(forKey: "SearchINSERTID") == nil { if let array = coreAdModelforJson([.init(level: 3, identifier: "ca-app-pub-1371732277241593/5323507386", ad: "AdMob", type: .Insert), .init(level: 2, identifier: "ca-app-pub-1371732277241593/6877962328", ad: "AdMob", type: .Insert), @@ -107,12 +117,18 @@ func coreDefaultValues() { UserDefaults.standard.set(array, forKey: "SearchINSERTID") } } + if UserDefaults.standard.string(forKey: "SearchNATIVEID") != nil { + UserDefaults.standard.removeObject(forKey: "SearchNATIVEID") + } if UserDefaults.standard.object(forKey: "SearchNATIVEID") == nil { if let array = coreAdModelforJson([.init(level: 3, identifier: "ca-app-pub-1371732277241593/5674216970", ad: "AdMob", type: .Native)]) { //存入默认开屏热启动广告ID UserDefaults.standard.set(array, forKey: "SearchNATIVEID") } } + if UserDefaults.standard.string(forKey: "PlayerINSERTID") != nil { + UserDefaults.standard.removeObject(forKey: "PlayerINSERTID") + } if UserDefaults.standard.object(forKey: "PlayerINSERTID") == nil { if let array = coreAdModelforJson([.init(level: 3, identifier: "ca-app-pub-1371732277241593/9569874154", ad: "AdMob", type: .Insert), .init(level: 2, identifier: "ca-app-pub-1371732277241593/8256792481", ad: "AdMob", type: .Insert), @@ -122,6 +138,9 @@ func coreDefaultValues() { UserDefaults.standard.set(array, forKey: "PlayerINSERTID") } } + if UserDefaults.standard.string(forKey: "SwitchINSERTID") != nil { + UserDefaults.standard.removeObject(forKey: "SwitchINSERTID") + } if UserDefaults.standard.object(forKey: "SwitchINSERTID") == nil { if let array = coreAdModelforJson([.init(level: 3, identifier: "ca-app-pub-1371732277241593/4990165586", ad: "AdMob", type: .Insert), .init(level: 2, identifier: "ca-app-pub-1371732277241593/5247485769", ad: "AdMob", type: .Insert), @@ -131,6 +150,9 @@ func coreDefaultValues() { UserDefaults.standard.set(array, forKey: "SwitchINSERTID") } } + if UserDefaults.standard.string(forKey: "LoadINSERTID") != nil { + UserDefaults.standard.removeObject(forKey: "LoadINSERTID") + } if UserDefaults.standard.object(forKey: "LoadINSERTID") == nil { if let array = coreAdModelforJson([.init(level: 3, identifier: "ca-app-pub-1371732277241593/4335559460", ad: "AdMob", type: .Insert), .init(level: 2, identifier: "ca-app-pub-1371732277241593/2398278378", ad: "AdMob", type: .Insert), @@ -139,6 +161,9 @@ func coreDefaultValues() { UserDefaults.standard.set(array, forKey: "LoadINSERTID") } } + if UserDefaults.standard.string(forKey: "LibraryINSERTID") != nil { + UserDefaults.standard.removeObject(forKey: "LibraryINSERTID") + } if UserDefaults.standard.object(forKey: "LibraryINSERTID") == nil { if let array = coreAdModelforJson([.init(level: 3, identifier: "ca-app-pub-1371732277241593/4607022200", ad: "AdMob", type: .Insert), .init(level: 2, identifier: "ca-app-pub-1371732277241593/3104538158", ad: "AdMob", type: .Insert), @@ -148,12 +173,18 @@ func coreDefaultValues() { UserDefaults.standard.set(array, forKey: "LibraryINSERTID") } } + if UserDefaults.standard.string(forKey: "LibraryNATIVEID") != nil { + UserDefaults.standard.removeObject(forKey: "LibraryNATIVEID") + } if UserDefaults.standard.object(forKey: "LibraryNATIVEID") == nil { if let array = coreAdModelforJson([.init(level: 3, identifier: "ca-app-pub-1371732277241593/4683255855", ad: "AdMob", type: .Native)]) { //存入默认开屏热启动广告ID UserDefaults.standard.set(array, forKey: "LibraryNATIVEID") } } + if UserDefaults.standard.string(forKey: "GlobalINSERTID") != nil { + UserDefaults.standard.removeObject(forKey: "GlobalINSERTID") + } if UserDefaults.standard.object(forKey: "GlobalINSERTID") == nil { if let array = coreAdModelforJson([.init(level: 3, identifier: "ca-app-pub-1371732277241593/9449223728", ad: "AdMob", type: .Insert)]) { //存入默认开屏热启动广告ID diff --git a/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_AdMobManager.swift b/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_AdMobManager.swift index a23d2f8..6f12610 100644 --- a/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_AdMobManager.swift +++ b/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_AdMobManager.swift @@ -14,7 +14,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont static let shared = MP_AdMobManager() private let sharedInstance = GADMobileAds.sharedInstance() ///广告总开关 - private var openAdStatus:Bool = false + private var openAdStatus:Bool = true ///广告过期时间(50分钟) private let expirationTime:TimeInterval = 3000 @@ -94,7 +94,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont //关闭插页广告开关 interstitialSwitch = false //重新加载后续的搜索插页广告 - DispatchQueue.main.asyncAfter(deadline: .now() + 20) { + DispatchQueue.main.asyncAfter(deadline: .now() + 10) { [weak self] in self?.loadSearchInterstitialAd { status in if status { @@ -116,7 +116,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont //关闭插页广告开关 interstitialSwitch = false //重新加载后续的播放插页广告 - DispatchQueue.main.asyncAfter(deadline: .now() + 20) { + DispatchQueue.main.asyncAfter(deadline: .now() + 10) { [weak self] in self?.loadPlayInterstitialAd { status in if status { @@ -138,7 +138,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont //关闭插页广告开关 interstitialSwitch = false //重新加载后续的切歌插页广告 - DispatchQueue.main.asyncAfter(deadline: .now() + 20) { + DispatchQueue.main.asyncAfter(deadline: .now() + 10) { [weak self] in self?.loadSwitchInterstitialAd { status in if status { @@ -160,7 +160,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont //关闭插页广告开关 interstitialSwitch = false //重新加载后续的下载插页广告 - DispatchQueue.main.asyncAfter(deadline: .now() + 20) { + DispatchQueue.main.asyncAfter(deadline: .now() + 10) { [weak self] in self?.loadLoadInterstitialAd { status in if status { @@ -182,7 +182,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont //关闭插页广告开关 interstitialSwitch = false //重新加载后续的曲库插页广告 - DispatchQueue.main.asyncAfter(deadline: .now() + 20) { + DispatchQueue.main.asyncAfter(deadline: .now() + 10) { [weak self] in self?.loadLibraryInterstitialAd { status in if status { @@ -204,7 +204,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont //关闭插页广告开关 interstitialSwitch = false //重新加载后续的全局插页广告 - DispatchQueue.main.asyncAfter(deadline: .now() + 20) { + DispatchQueue.main.asyncAfter(deadline: .now() + 10) { [weak self] in self?.loadGlobalInterstitialAd { status in if status { @@ -268,14 +268,14 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont print("搜索插页广告加载失败") } } - self.loadSwitchInterstitialAd { status in + loadSwitchInterstitialAd { status in if status { print("成功加载切歌插页广告") }else { print("切歌插页广告加载失败") } } - self.loadLibraryInterstitialAd { status in + loadLibraryInterstitialAd { status in if status { print("成功加载曲库插页广告") }else { @@ -283,14 +283,14 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont } } - self.loadGlobalInterstitialAd { status in + loadGlobalInterstitialAd { status in if status { print("成功加载全局插页广告") }else { print("全局插页广告加载失败") } } - self.loadLoadInterstitialAd { status in + loadLoadInterstitialAd { status in if status { print("成功加载下载插页广告") }else { @@ -358,32 +358,48 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont ///异步加载开屏广告 func loadOpenAd(_ type:OpenType, level:Int = 0, completion: @escaping (Bool) -> Void) { guard openAdStatus else {return} - //检索是否超过了对应的id组的阶级数量 - var item:MPPositive_AdModelModel - switch type { - case .ICE: - guard level <= (OpenICEID.count-1) else { - print("冷启动广告组已经全部加载失败,停止继续加载") - MP_AnalyticsManager.shared.cold_ads_showFailureAction("No Ads Fill") - completion(false) - return - } - item = OpenICEID[level] - case .HOST: - guard level <= (OpenHOSTID.count-1) else { - print("热启动广告组已经全部加载失败,停止继续加载") - MP_AnalyticsManager.shared.hot_ads_showFailureAction("No Ads Fill") - completion(false) - return - } - item = OpenHOSTID[level] - } // 检测当前是否有广告或者有广告正在加载 if isLoadingOpenAd || isOpenAdAvailable() { // 有广告或有广告在加载 completion(false) return } + //检索是否超过了对应的id组的阶级数量 + var item:MPPositive_AdModelModel + switch type { + case .ICE: + guard OpenICEID.isEmpty == false else { + //冷启动无数据 + MP_AnalyticsManager.shared.cold_ads_showFailureAction("No IDs") + //重新获取数据 + reloadAdMobIDs() + completion(false) + return + } + guard level < (OpenICEID.count) else { + print("冷启动广告组已经全部加载失败,停止继续加载") + MP_AnalyticsManager.shared.cold_ads_loadFailureAction("No Ads Fill") + completion(false) + return + } + item = OpenICEID[level] + case .HOST: + guard OpenHOSTID.isEmpty == false else { + //热启动无数据 + MP_AnalyticsManager.shared.hot_ads_showFailureAction("No IDs") + //重新获取数据 + reloadAdMobIDs() + completion(false) + return + } + guard level < (OpenHOSTID.count) else { + print("热启动广告组已经全部加载失败,停止继续加载") + MP_AnalyticsManager.shared.hot_ads_loadFailureAction("No Ads Fill") + completion(false) + return + } + item = OpenHOSTID[level] + } isLoadingOpenAd = true //判断需要生成什么广告 if item.type == .Open { @@ -394,6 +410,12 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont guard let self = self else { return } if let error = error { print("加载开屏广告失败,失败原因: \(error.localizedDescription),已下调广告ID等级,重新加载") + switch type { + case .ICE: + MP_AnalyticsManager.shared.cold_ads_loadFailureAction(error.localizedDescription) + case .HOST: + MP_AnalyticsManager.shared.hot_ads_loadFailureAction(error.localizedDescription) + } self.isLoadingOpenAd = false loadOpenAd(type, level: level+1, completion: completion) } else { @@ -414,6 +436,12 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont guard let self = self else { return } if let error = error { print("加载开屏广告失败,失败原因: \(error.localizedDescription),已下调广告ID等级,重新加载") + switch type { + case .ICE: + MP_AnalyticsManager.shared.cold_ads_loadFailureAction(error.localizedDescription) + case .HOST: + MP_AnalyticsManager.shared.hot_ads_loadFailureAction(error.localizedDescription) + } self.isLoadingOpenAd = false loadOpenAd(type, level: level+1, completion: completion) } else { @@ -612,21 +640,28 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont //异步加载搜索插页广告 func loadSearchInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) { guard openAdStatus else {return} - guard level <= (SearchINSERTID.count-1) else { - print("搜索插页广告组已经全部加载失败,停止继续加载") - MP_AnalyticsManager.shared.search_ads_showFailureAction("No Ads Fill") - //开始加载全局插页 - loadGlobalInterstitialAd { status in - completion(status) - } - return - } // 检测当前是否有广告或者有广告正在加载 if isLoadingSearchInterstitialAd || isSearchInterstitialAdAvailable() { // 有广告或有广告在加载 completion(false) return } + guard SearchINSERTID.isEmpty == false else { + MP_AnalyticsManager.shared.search_ads_showFailureAction("No IDs") + //重新获取数据 + reloadAdMobIDs() + completion(false) + return + } + guard level < (SearchINSERTID.count) else { + print("搜索插页广告组已经全部加载失败,停止继续加载") + MP_AnalyticsManager.shared.search_ads_loadFailureAction("No Ads Fill") + //开始加载全局插页 + loadGlobalInterstitialAd { status in + completion(status) + } + return + } isLoadingSearchInterstitialAd = true let item = SearchINSERTID[level] //加载搜索插页广告 @@ -635,6 +670,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont guard let self = self else { return } if let error = error { print("加载搜索插页广告失败,失败原因: \(error.localizedDescription),已下调广告ID等级,重新加载") + MP_AnalyticsManager.shared.search_ads_loadFailureAction(error.localizedDescription) self.isLoadingSearchInterstitialAd = false loadSearchInterstitialAd(level+1, completion: completion) } else { @@ -718,21 +754,29 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont //异步加载播放插页广告 func loadPlayInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) { guard openAdStatus else {return} - guard level <= (PlayerINSERTID.count-1) else { - print("播放插页广告组已经全部加载失败,停止继续加载") - MP_AnalyticsManager.shared.play_ads_showFailureAction("No Ads Fill") - //开始加载全局插页 - loadGlobalInterstitialAd { status in - completion(status) - } - return - } // 检测当前是否有广告或者有广告正在加载 if isLoadingPlayInterstitialAd || isPlayInterstitialAdAvailable() { // 有广告或有广告在加载 completion(false) return } + guard PlayerINSERTID.isEmpty == false else { + MP_AnalyticsManager.shared.play_ads_showFailureAction("No IDs") + //重新获取数据 + reloadAdMobIDs() + completion(false) + return + } + + guard level < (PlayerINSERTID.count) else { + print("播放插页广告组已经全部加载失败,停止继续加载") + MP_AnalyticsManager.shared.play_ads_loadFailureAction("No Ads Fill") + //开始加载全局插页 + loadGlobalInterstitialAd { status in + completion(status) + } + return + } isLoadingPlayInterstitialAd = true let item = PlayerINSERTID[level] //加载播放插页广告 @@ -741,6 +785,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont guard let self = self else { return } if let error = error { print("加载播放插页广告失败,失败原因: \(error.localizedDescription),已下调广告ID等级,重新加载") + MP_AnalyticsManager.shared.play_ads_loadFailureAction(error.localizedDescription) self.isLoadingPlayInterstitialAd = false loadPlayInterstitialAd(level+1, completion: completion) } else { @@ -825,21 +870,28 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont //异步加载切歌插页广告 func loadSwitchInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) { guard openAdStatus else {return} - guard level <= (SwitchINSERTID.count-1) else { - print("切歌插页广告组已经全部加载失败,停止继续加载") - MP_AnalyticsManager.shared.cut_ads_showFailureAction("No Ads Fill") - //开始加载全局插页 - loadGlobalInterstitialAd { status in - completion(status) - } - return - } // 检测当前是否有广告或者有广告正在加载 if isLoadingSwitchInterstitialAd || isSwitchInterstitialAdAvailable() { // 有广告或有广告在加载 completion(false) return } + guard SwitchINSERTID.isEmpty == false else { + MP_AnalyticsManager.shared.cut_ads_showFailureAction("No IDs") + //重新获取数据 + reloadAdMobIDs() + completion(false) + return + } + guard level < (SwitchINSERTID.count) else { + print("切歌插页广告组已经全部加载失败,停止继续加载") + MP_AnalyticsManager.shared.cut_ads_loadFailureAction("No Ads Fill") + //开始加载全局插页 + loadGlobalInterstitialAd { status in + completion(status) + } + return + } isLoadingSwitchInterstitialAd = true let item = SwitchINSERTID[level] //加载播放插页广告 @@ -848,6 +900,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont guard let self = self else { return } if let error = error { print("加载切歌插页广告失败,失败原因: \(error.localizedDescription),已下调广告ID等级,重新加载") + MP_AnalyticsManager.shared.cut_ads_loadFailureAction(error.localizedDescription) self.isLoadingSwitchInterstitialAd = false loadSwitchInterstitialAd(level+1, completion: completion) } else { @@ -931,21 +984,28 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont //异步加载下载插页广告 func loadLoadInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) { guard openAdStatus else {return} - guard level <= (LoadINSERTID.count-1) else { - print("下载插页广告组已经全部加载失败,停止继续加载") - MP_AnalyticsManager.shared.dl_ads_showFailureAction("No Ads Fill") - //开始加载全局插页 - loadGlobalInterstitialAd { status in - completion(status) - } - return - } // 检测当前是否有广告或者有广告正在加载 if isLoadingLoadInterstitialAd || isLoadInterstitialAdAvailable() { // 有广告或有广告在加载 completion(false) return } + guard LoadINSERTID.isEmpty == false else { + MP_AnalyticsManager.shared.dl_ads_showFailureAction("No IDs") + //重新获取数据 + reloadAdMobIDs() + completion(false) + return + } + guard level < (LoadINSERTID.count) else { + print("下载插页广告组已经全部加载失败,停止继续加载") + MP_AnalyticsManager.shared.dl_ads_loadFailureAction("No Ads Fill") + //开始加载全局插页 + loadGlobalInterstitialAd { status in + completion(status) + } + return + } isLoadingLoadInterstitialAd = true let item = LoadINSERTID[level] //加载下载插页广告 @@ -954,6 +1014,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont guard let self = self else { return } if let error = error { print("加载下载插页广告失败,失败原因: \(error.localizedDescription),已下调广告ID等级,重新加载") + MP_AnalyticsManager.shared.dl_ads_loadFailureAction(error.localizedDescription) self.isLoadingLoadInterstitialAd = false loadLoadInterstitialAd(level+1, completion: completion) } else { @@ -1162,21 +1223,28 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont //异步加载曲库插页广告 func loadLibraryInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) { guard openAdStatus else {return} - guard level <= (LibraryINSERTID.count-1) else { - print("曲库插页广告组已经全部加载失败,停止继续加载") - MP_AnalyticsManager.shared.listclk_ads_showFailureAction("No Ads Fill") - //开始加载全局插页 - loadGlobalInterstitialAd { status in - completion(status) - } - return - } // 检测当前是否有广告或者有广告正在加载 if isLoadingLibraryInterstitialAd || isLibraryInterstitialAdAvailable() { // 有广告或有广告在加载 completion(false) return } + guard LibraryINSERTID.isEmpty == false else { + MP_AnalyticsManager.shared.listclk_ads_showFailureAction("No IDs") + //重新获取数据 + reloadAdMobIDs() + completion(false) + return + } + guard level < (LibraryINSERTID.count) else { + print("曲库插页广告组已经全部加载失败,停止继续加载") + MP_AnalyticsManager.shared.listclk_ads_loadFailureAction("No Ads Fill") + //开始加载全局插页 + loadGlobalInterstitialAd { status in + completion(status) + } + return + } isLoadingLibraryInterstitialAd = true let item = LibraryINSERTID[level] //加载曲库插页广告 @@ -1185,6 +1253,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont guard let self = self else { return } if let error = error { print("加载曲库插页广告失败,失败原因: \(error.localizedDescription),已下调广告ID等级,重新加载") + MP_AnalyticsManager.shared.listclk_ads_loadFailureAction(error.localizedDescription) self.isLoadingLibraryInterstitialAd = false loadLibraryInterstitialAd(level+1, completion: completion) } else { @@ -1271,17 +1340,17 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont //异步加载全局插页广告 func loadGlobalInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) { guard openAdStatus else {return} - guard level <= (GlobalINSERTID.count-1) else { - print("全局插页广告组已经全部加载失败,停止继续加载") - completion(false) - return - } // 检测当前是否有广告或者有广告正在加载 if isLoadingGlobalInterstitialAd || isGlobalInterstitialAdAvailable() { // 有广告或有广告在加载 completion(false) return } + guard level < (GlobalINSERTID.count) else { + print("全局插页广告组已经全部加载失败,停止继续加载") + completion(false) + return + } isLoadingGlobalInterstitialAd = true let item = GlobalINSERTID[level] //加载全局插页广告 diff --git a/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_AnalyticsManager.swift b/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_AnalyticsManager.swift index 2d8e707..8656cd5 100644 --- a/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_AnalyticsManager.swift +++ b/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_AnalyticsManager.swift @@ -135,13 +135,13 @@ class MP_AnalyticsManager: NSObject { } } //将array转为jsonData - if array.isEmpty != true, let data = coreAdModelforJson(array) { + if array.isEmpty == false, let data = coreAdModelforJson(array) { + UserDefaults.standard.removeObject(forKey: key) + //重新更新内容 + print("Reload--\(key)") UserDefaults.standard.set(data, forKey: key) - }else { - UserDefaults.standard.set(nil, forKey: key) } } - print("更新了所有广告ID") MP_AdMobManager.shared.reloadAdMobIDs() } //更新版本数据设置 @@ -424,6 +424,8 @@ class MP_AnalyticsManager: NSObject { //MARK: - 广告埋点事件 //冷启动展示机会 private let cold_ads_chance:String = "cold_ads_chance" + //冷启动加载失败 + private let cold_ads_loadFailure:String = "cold_ads_loadFailure" //冷启动展示成功 private let cold_ads_showSuccess:String = "cold_ads_showSuccess" //冷启动展示失败 @@ -431,6 +433,8 @@ class MP_AnalyticsManager: NSObject { //热启动展示机会 private let hot_ads_chance:String = "hot_ads_chance" + //热启动加载失败 + private let hot_ads_loadFailure:String = "hot_ads_loadFailure" //热启动展示成功 private let hot_ads_showSuccess:String = "hot_ads_showSuccess" //热启动展示失败 @@ -438,6 +442,8 @@ class MP_AnalyticsManager: NSObject { //搜索展示机会 private let search_ads_chance:String = "search_ads_chance" + //搜索加载失败 + private let search_ads_loadFailure:String = "search_ads_loadFailure" //搜索展示次数 private let search_ads_showSuccess:String = "search_ads_showSuccess" //搜索展示次数 @@ -450,6 +456,8 @@ class MP_AnalyticsManager: NSObject { //播放展示机会 private let play_ads_chance:String = "play_ads_chance" + //播放加载失败 + private let play_ads_loadFailure:String = "play_ads_loadFailure" //播放展示次数 private let play_ads_showSuccess:String = "play_ads_showSuccess" //播放展示次数 @@ -457,6 +465,8 @@ class MP_AnalyticsManager: NSObject { //下载展示机会 private let dl_ads_chance:String = "dl_ads_chance" + //下载加载失败 + private let dl_ads_loadFailure:String = "dl_ads_loadFailure" //下载展示次数 private let dl_ads_showSuccess:String = "dl_ads_showSuccess" //下载展示次数 @@ -464,6 +474,8 @@ class MP_AnalyticsManager: NSObject { //切歌展示机会 private let cut_ads_chance:String = "cut_ads_chance" + //切歌加载失败 + private let cut_ads_loadFailure:String = "cut_ads_loadFailure" //切歌展示次数 private let cut_ads_showSuccess:String = "cut_ads_showSuccess" //切歌展示次数 @@ -471,6 +483,8 @@ class MP_AnalyticsManager: NSObject { //列表进入机会 private let listclk_ads_chance:String = "listclk_ads_chance" + //列表加载失败 + private let listclk_ads_loadFailure:String = "listclk_ads_loadFailure" //列表进入次数 private let listclk_ads_showSuccess:String = "listclk_ads_showSuccess" //列表进入次数 @@ -485,6 +499,7 @@ class MP_AnalyticsManager: NSObject { private let list_ads_chance:String = "list_ads_chance" //列表原生次数 private let list_ads_show:String = "list_ads_show" + //总价值上报 private let ad_session_total_value:String = "ad_session_total_value" @@ -533,6 +548,12 @@ class MP_AnalyticsManager: NSObject { func cold_ads_chanceAction() { Analytics.logEvent(cold_ads_chance, parameters: ["CS_STATUS":isOLD ? "Old":"New"]) } + ///冷启动加载失败 + func cold_ads_loadFailureAction(_ error:String) { + let parameters:[String:String] = ["CS_STATUS":isOLD ? "Old":"New", + "CS_ERROR":error] + Analytics.logEvent(cold_ads_loadFailure, parameters: parameters) + } ///冷启动展示成功 func cold_ads_showSuccessAction(_ responseInfo:GADResponseInfo, adValue:GADAdValue) { let parameters:[String:Any] = infoToParameters(responseInfo, adValue: adValue) @@ -551,6 +572,12 @@ class MP_AnalyticsManager: NSObject { func hot_ads_chanceAction() { Analytics.logEvent(hot_ads_chance, parameters: ["CS_STATUS":isOLD ? "Old":"New"]) } + ///热启动加载失败 + func hot_ads_loadFailureAction(_ error:String) { + let parameters:[String:String] = ["CS_STATUS":isOLD ? "Old":"New", + "CS_ERROR":error] + Analytics.logEvent(hot_ads_loadFailure, parameters: parameters) + } ///热启动展示成功 func hot_ads_showSuccessAction(_ responseInfo:GADResponseInfo, adValue:GADAdValue) { let parameters:[String:Any] = infoToParameters(responseInfo, adValue: adValue) @@ -569,6 +596,12 @@ class MP_AnalyticsManager: NSObject { func search_ads_chanceAction() { Analytics.logEvent(search_ads_chance, parameters: ["CS_STATUS":isOLD ? "Old":"New"]) } + ///搜索加载失败 + func search_ads_loadFailureAction(_ error:String) { + let parameters:[String:String] = ["CS_STATUS":isOLD ? "Old":"New", + "CS_ERROR":error] + Analytics.logEvent(search_ads_loadFailure, parameters: parameters) + } ///搜索展示成功 func search_ads_showSuccessAction(_ responseInfo:GADResponseInfo, adValue:GADAdValue) { let parameters:[String:Any] = infoToParameters(responseInfo, adValue: adValue) @@ -598,6 +631,12 @@ class MP_AnalyticsManager: NSObject { func play_ads_chanceAction() { Analytics.logEvent(play_ads_chance, parameters: ["CS_STATUS":isOLD ? "Old":"New"]) } + ///播放加载失败 + func play_ads_loadFailureAction(_ error:String) { + let parameters:[String:String] = ["CS_STATUS":isOLD ? "Old":"New", + "CS_ERROR":error] + Analytics.logEvent(play_ads_loadFailure, parameters: parameters) + } ///播放展示成功 func play_ads_showSuccessAction(_ responseInfo:GADResponseInfo, adValue:GADAdValue) { let parameters:[String:Any] = infoToParameters(responseInfo, adValue: adValue) @@ -616,6 +655,12 @@ class MP_AnalyticsManager: NSObject { func dl_ads_chanceAction() { Analytics.logEvent(dl_ads_chance, parameters: ["CS_STATUS":isOLD ? "Old":"New"]) } + ///下载加载失败 + func dl_ads_loadFailureAction(_ error:String) { + let parameters:[String:String] = ["CS_STATUS":isOLD ? "Old":"New", + "CS_ERROR":error] + Analytics.logEvent(dl_ads_loadFailure, parameters: parameters) + } ///下载展示成功 func dl_ads_showSuccessAction(_ responseInfo:GADResponseInfo, adValue:GADAdValue) { let parameters:[String:Any] = infoToParameters(responseInfo, adValue: adValue) @@ -634,6 +679,12 @@ class MP_AnalyticsManager: NSObject { func cut_ads_chanceAction() { Analytics.logEvent(cut_ads_chance, parameters: ["CS_STATUS":isOLD ? "Old":"New"]) } + ///切歌加载失败 + func cut_ads_loadFailureAction(_ error:String) { + let parameters:[String:String] = ["CS_STATUS":isOLD ? "Old":"New", + "CS_ERROR":error] + Analytics.logEvent(cut_ads_loadFailure, parameters: parameters) + } ///切歌展示成功 func cut_ads_showSuccessAction(_ responseInfo:GADResponseInfo, adValue:GADAdValue) { let parameters:[String:Any] = infoToParameters(responseInfo, adValue: adValue) @@ -652,6 +703,12 @@ class MP_AnalyticsManager: NSObject { func listclk_ads_chanceAction() { Analytics.logEvent(listclk_ads_chance, parameters: ["CS_STATUS":isOLD ? "Old":"New"]) } + ///列表加载失败 + func listclk_ads_loadFailureAction(_ error:String) { + let parameters:[String:String] = ["CS_STATUS":isOLD ? "Old":"New", + "CS_ERROR":error] + Analytics.logEvent(listclk_ads_loadFailure, parameters: parameters) + } ///列表进入成功 func listclk_ads_showSuccessAction(_ responseInfo:GADResponseInfo, adValue:GADAdValue) { let parameters:[String:Any] = infoToParameters(responseInfo, adValue: adValue) diff --git a/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_NetWorkManager.swift b/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_NetWorkManager.swift index 5368b87..af68d5d 100644 --- a/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_NetWorkManager.swift +++ b/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_NetWorkManager.swift @@ -995,68 +995,8 @@ extension MP_NetWorkManager { } } private func requestAndroidPostPlayer(_ url:URL, videoId:String, parameters:Parameters, completion:@escaping((([String],[Int],[String])?, [String]?) -> Void)) { - // 创建 Headers - let headers: HTTPHeaders = [ - "Accept": "*/*", - "Accept-Encoding": "gzip, deflate, br, zstd", - "Accept-Language": "zh-CN,zh;q=0.9", - "Content-Type": "application/json", - "Origin": "https://music.youtube.com", - "Referer": "https://music.youtube.com/watch?v=\(videoId)", - "User-Agent": "com.google.android.apps.youtube.music/5.28.1 (Linux; U; Android 11) gzip", - "X-Goog-Visitor-Id": visitorData ?? "", - "X-Youtube-Bootstrap-Logged-In": "false", - "X-Youtube-Client-Name": "67", - "X-Youtube-Client-Version": clientVersion ?? "" - ] - // 创建 Cookies - let cookies: [HTTPCookie] = [ - HTTPCookie(properties: [ - .domain: "music.youtube.com", - .path: "/", - .name: "YSC", - .value: "8oDrKFv_xIg", - .secure: "TRUE", - .expires: NSDate(timeIntervalSinceNow: 31556926) - ])!, - HTTPCookie(properties: [ - .domain: "music.youtube.com", - .path: "/", - .name: "VISITOR_INFO1_LIVE", - .value: "kBFGqoTUcHk", - .secure: "TRUE", - .expires: NSDate(timeIntervalSinceNow: 31556926) - ])!, - HTTPCookie(properties: [ - .domain: "music.youtube.com", - .path: "/", - .name: "VISITOR_PRIVACY_METADATA", - .value: "CgJTRxIEGgAgIQ%3D%3D", - .secure: "TRUE", - .expires: NSDate(timeIntervalSinceNow: 31556926) - ])!, - HTTPCookie(properties: [ - .domain: "music.youtube.com", - .path: "/", - .name: "_gcl_au", - .value: "1.1.1865031595.1721989780", - .secure: "TRUE", - .expires: NSDate(timeIntervalSinceNow: 31556926) - ])!, - HTTPCookie(properties: [ - .domain: "music.youtube.com", - .path: "/", - .name: "PREF", - .value: "repeat=NONE&autoplay=true", - .secure: "TRUE", - .expires: NSDate(timeIntervalSinceNow: 31556926) - ])! - ] - // 获取共享的 HTTPCookieStorage 实例并设置 Cookies - let cookieStorage = HTTPCookieStorage.shared - cookies.forEach { cookieStorage.setCookie($0) } //发送post请求 - let request = PlayerSeesion.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseDecodable(of: JsonAndroidPlayer.self) { [weak self] (response) in + let request = PlayerSeesion.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseDecodable(of: JsonAndroidPlayer.self) { [weak self] (response) in guard let self = self else {return} self.playerRequests[videoId] = nil // 清除请求 switch response.result { diff --git a/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_PlayerManager.swift b/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_PlayerManager.swift index c51798a..17f1d97 100644 --- a/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_PlayerManager.swift +++ b/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_PlayerManager.swift @@ -309,32 +309,32 @@ class MP_PlayerManager:NSObject{ if startAction != nil { startActionBlock = startAction } - //覆盖播放器原有的playerItem - player.replaceCurrentItem(with: loadPlayer?.currentVideo?.resourcePlayerItem) - if center == nil { - setCommandCenter() - } - //启动计时器 - startTimer() - //对当前播放PlayerItem设置监听状态 - if loadPlayer?.currentVideo?.isKVO == false { - //准备状态 - statusObservation?.invalidate() - statusObservation = loadPlayer?.currentVideo?.resourcePlayerItem?.observe(\.status, options: [.old,.new], changeHandler: { [weak self] item, change in - guard let self = self else {return} - if item.status == .readyToPlay { - //判断当前播放器是否在播放当前音乐中 - if playState != .Playing { - //当statuVlaue值等于playerItem准备播放的值,说明已经准备好播放 - print("当前音乐-\(loadPlayer?.currentVideo?.title ?? "") 已经准备好播放") - } - }else { - if let currentVideo = loadPlayer?.currentVideo { - print("当前音乐-\(currentVideo.title ?? "") 未做好准备播放,失败原因是\(currentVideo.resourcePlayerItem.error?.localizedDescription ?? "")") - MP_AnalyticsManager.shared.player_b_failure_errorAction(currentVideo.song.videoId ?? "", videoname: currentVideo.title ?? "", artistname: currentVideo.song.shortBylineText ?? "", error: currentVideo.resourcePlayerItem.error?.localizedDescription ?? "Failed to buffer data") - if loadPlayer?.currentVideo?.isKVO == true { + if let currentVideo = loadPlayer?.currentVideo { + //覆盖播放器原有的playerItem + player.replaceCurrentItem(with: currentVideo.resourcePlayerItem) + if center == nil { + setCommandCenter() + } + //启动计时器 + startTimer() + //对当前播放PlayerItem设置监听状态 + if currentVideo.isKVO == false { + //准备状态 + statusObservation?.invalidate() + statusObservation = currentVideo.resourcePlayerItem?.observe(\.status, options: [.old,.new], changeHandler: { [weak self] item, change in + guard let self = self else {return} + if item.status == .readyToPlay { + //判断当前播放器是否在播放当前音乐中 + if playState != .Playing { + //当statuVlaue值等于playerItem准备播放的值,说明已经准备好播放 + print("当前音乐-\(currentVideo.title ?? "") 已经准备好播放") + } + }else { + print("当前音乐-\(currentVideo.title ?? "") 未做好准备播放,失败原因是\(currentVideo.resourcePlayerItem?.error?.localizedDescription ?? "")") + MP_AnalyticsManager.shared.player_b_failure_errorAction(currentVideo.song.videoId ?? "", videoname: currentVideo.title ?? "", artistname: currentVideo.song.shortBylineText ?? "", error: currentVideo.resourcePlayerItem?.error?.localizedDescription ?? "Failed to buffer data") + if currentVideo.isKVO == true { suspendTimer() - loadPlayer?.currentVideo?.isKVO = false + currentVideo.isKVO = false statusObservation?.invalidate() loadedTimeRangesObservation?.invalidate() playbackLikelyToKeepUpObservation?.invalidate() @@ -346,63 +346,63 @@ class MP_PlayerManager:NSObject{ } } } - } - }) - //当前缓冲值 - loadedTimeRangesObservation?.invalidate() - loadedTimeRangesObservation = loadPlayer?.currentVideo?.resourcePlayerItem?.observe(\.loadedTimeRanges, options: [.old,.new], changeHandler: { [weak self] item, change in - guard let self = self else {return} - cacheLoadTimes() - }) - //是否具备足够播放的能力 - playbackLikelyToKeepUpObservation?.invalidate() - playbackLikelyToKeepUpObservation = loadPlayer?.currentVideo?.resourcePlayerItem?.observe(\.isPlaybackLikelyToKeepUp, options: [.old,.new], changeHandler: { [weak self] item, change in - guard let self = self else {return} - if let playbackLikelyToKeepUp = change.newValue, playbackLikelyToKeepUp == true { - if playState != .Playing && playState != .Pause { - //还未播放当前音乐,启动播放 - playState = .Playing - //检索是否展示了插页广告 - if isAdLate != true { - //当前是否上次播放展示状态,是的话,手动暂停 - if isLast { - pause() - isLast = false - }else { - player.play() + }) + //当前缓冲值 + loadedTimeRangesObservation?.invalidate() + loadedTimeRangesObservation = currentVideo.resourcePlayerItem?.observe(\.loadedTimeRanges, options: [.old,.new], changeHandler: { [weak self] item, change in + guard let self = self else {return} + cacheLoadTimes() + }) + //是否具备足够播放的能力 + playbackLikelyToKeepUpObservation?.invalidate() + playbackLikelyToKeepUpObservation = currentVideo.resourcePlayerItem?.observe(\.isPlaybackLikelyToKeepUp, options: [.old,.new], changeHandler: { [weak self] item, change in + guard let self = self else {return} + if let playbackLikelyToKeepUp = change.newValue, playbackLikelyToKeepUp == true { + if playState != .Playing && playState != .Pause { + //还未播放当前音乐,启动播放 + playState = .Playing + //检索是否展示了插页广告 + if isAdLate != true { + //当前是否上次播放展示状态,是的话,手动暂停 + if isLast { + pause() + isLast = false + }else { + player.play() + } } - } - //暂停计时器,并获取延时值 - suspendTimer() - if let currentVideo = loadPlayer.currentVideo { - MP_AnalyticsManager.shared.player_b_success_actionAction(currentVideo.song.videoId ?? "", videoname: currentVideo.title ?? "", artistname: currentVideo.song.shortBylineText ?? "") + //暂停计时器,并获取延时值 + suspendTimer() + if let currentVideo = loadPlayer?.currentVideo { + MP_AnalyticsManager.shared.player_b_success_actionAction(currentVideo.song.videoId ?? "", videoname: currentVideo.title ?? "", artistname: currentVideo.song.shortBylineText ?? "") + } + //执行开始播放闭包 + if startActionBlock != nil { + startActionBlock!() + } + } - //执行开始播放闭包 - if startActionBlock != nil { - startActionBlock!() - } - + }else { + //没有足够的数据支持播放 + player.pause() + playState = .Null } - }else { - //没有足够的数据支持播放 - player.pause() - playState = .Null - } - }) - //报错提醒 - errorObservation?.invalidate() - errorObservation = loadPlayer?.currentVideo?.resourcePlayerItem?.observe(\.error, options: [.old,.new], changeHandler: { [weak self] item, change in - guard let self = self else {return} - if let error = change.newValue, let nsError = error { - print("当前音乐-\(loadPlayer?.currentVideo?.title ?? "") 未做好准备播放,失败原因是\(nsError.localizedDescription)") - MP_AnalyticsManager.shared.player_b_failure_errorAction(loadPlayer?.currentVideo?.song.videoId ?? "", videoname: loadPlayer?.currentVideo?.title ?? "", artistname: loadPlayer?.currentVideo?.song.shortBylineText ?? "", error: nsError.localizedDescription) - } - }) - loadPlayer?.currentVideo?.isKVO = true - //将进度回归为0 - player.seek(to: .zero) - updateNowPlayingInfo() + }) + //报错提醒 + errorObservation?.invalidate() + errorObservation = currentVideo.resourcePlayerItem?.observe(\.error, options: [.old,.new], changeHandler: { [weak self] item, change in + guard let self = self else {return} + if let error = change.newValue, let nsError = error { + print("当前音乐-\(currentVideo.title ?? "") 未做好准备播放,失败原因是\(nsError.localizedDescription)") + MP_AnalyticsManager.shared.player_b_failure_errorAction(currentVideo.song.videoId ?? "", videoname: currentVideo.title ?? "", artistname: currentVideo.song.shortBylineText ?? "", error: nsError.localizedDescription) + } + }) + currentVideo.isKVO = true + //将进度回归为0 + player.seek(to: .zero) + updateNowPlayingInfo() + } } } ///启动计时器 diff --git a/relax.offline.mp3.music/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_SongViewModel.swift b/relax.offline.mp3.music/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_SongViewModel.swift index 38099dc..ae071d4 100644 --- a/relax.offline.mp3.music/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_SongViewModel.swift +++ b/relax.offline.mp3.music/MP/MPPositive/Models/ViewModels/ListViewModels/MPPositive_SongViewModel.swift @@ -13,7 +13,7 @@ class MPPositive_SongViewModel: NSObject { ///排序号 var index:Int! ///播放实例 - @objc dynamic var resourcePlayerItem:MP_AVPlayerItem! + @objc dynamic var resourcePlayerItem:MP_AVPlayerItem? ///播放媒体 var resourcePlayerAsset:MP_AVURLAsset! ///播放路径 diff --git a/relax.offline.mp3.music/MP/MPPositive/ViewControllers/Search(搜索页)/MPPositive_SearchViewController.swift b/relax.offline.mp3.music/MP/MPPositive/ViewControllers/Search(搜索页)/MPPositive_SearchViewController.swift index 643c7bc..8eb3732 100644 --- a/relax.offline.mp3.music/MP/MPPositive/ViewControllers/Search(搜索页)/MPPositive_SearchViewController.swift +++ b/relax.offline.mp3.music/MP/MPPositive/ViewControllers/Search(搜索页)/MPPositive_SearchViewController.swift @@ -188,9 +188,13 @@ class MPPositive_SearchViewController: MPPositive_BaseViewController { extension MPPositive_SearchViewController: UICollectionViewDataSource, UICollectionViewDelegate, MPPositive_TagLayoutDelegate { func waterFlowLayout(_ layout: MPPositive_TagFlowLayout, indexPath: IndexPath) -> CGFloat { - let text = historys[indexPath.row].text ?? "" - let textWidth = text.textAutoWidth(height: 11.5 * width, font: .systemFont(ofSize: 12 * width, weight: .medium)) + (43 * width) - return textWidth + if indexPath.row < historys.count { + let text = historys[indexPath.row].text ?? "" + let textWidth = text.textAutoWidth(height: 11.5 * width, font: .systemFont(ofSize: 12 * width, weight: .medium)) + (43 * width) + return textWidth + }else { + return 0 + } } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { @@ -273,8 +277,9 @@ class MPPositive_TagFlowLayout: UICollectionViewFlowLayout { let array = super.layoutAttributesForElements(in: rect) var mutArray = [UICollectionViewLayoutAttributes]() array?.forEach({ (attrs) in - let theAttrs = layoutAttributesForItem(at: attrs.indexPath) - mutArray.append(theAttrs!) + if let theAttrs = layoutAttributesForItem(at: attrs.indexPath) { + mutArray.append(theAttrs) + } }) layoutAttributeds = mutArray return mutArray