1882 lines
84 KiB
Swift
1882 lines
84 KiB
Swift
//
|
||
// MP_AdMobManager.swift
|
||
// relax.offline.mp3.music
|
||
//
|
||
// Created by Mr.Zhou on 2024/6/14.
|
||
//
|
||
|
||
import UIKit
|
||
import AVFoundation
|
||
import GoogleMobileAds
|
||
import AppLovinAdapter
|
||
import AppLovinSDK
|
||
import LiftoffMonetizeAdapter
|
||
import VungleAdsSDK
|
||
import PangleAdapter
|
||
import PAGAdSDK
|
||
import IronSourceAdapter
|
||
import IronSource
|
||
import MintegralAdapter
|
||
import MTGSDK
|
||
import ChartboostSDK
|
||
import ChartboostAdapter
|
||
|
||
///AdMob广告管理器
|
||
class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenContentDelegate, GADNativeAdLoaderDelegate, GADNativeAdDelegate, GADVideoControllerDelegate {
|
||
static let shared = MP_AdMobManager()
|
||
///广告总开关
|
||
private var openAdStatus:Bool = MP_ADSimpleManager.shared.openAdStatus
|
||
///内部使用广告开光
|
||
private var internalAdStatus:Bool = MP_ADSimpleManager.shared.internalAdStatus
|
||
|
||
private let sharedInstance = GADMobileAds.sharedInstance()
|
||
///广告过期时间(50分钟)
|
||
private let expirationTime:TimeInterval = 3000
|
||
|
||
//检测广告是否过期
|
||
private func wasAdexpirationTime(_ date:Date?) -> Bool {
|
||
guard let loadTime = date else { return false }
|
||
// Check if ad was loaded more than four hours ago.
|
||
return Date().timeIntervalSince(loadTime) < expirationTime
|
||
}
|
||
//MARK: - 插页广告总设置
|
||
///插页广告总开关
|
||
private var interstitialSwitch:Bool = false{
|
||
didSet{
|
||
DispatchQueue.main.async {
|
||
[weak self] in
|
||
MPSideA_MediaCenterManager.shared.isAdLate = self?.interstitialSwitch
|
||
}
|
||
}
|
||
}
|
||
///插页广告显示时间
|
||
var interstitialDate:Date?
|
||
///插页广告间隔秒数(默认40秒)
|
||
private var interstitialDuration:TimeInterval{
|
||
get{
|
||
if let times = UserDefaults.standard.object(forKey: "InterstitialDuration") as? TimeInterval {
|
||
return times
|
||
}else {
|
||
return 40
|
||
}
|
||
}
|
||
}
|
||
///中介间隔秒数
|
||
private var intermediaryDuration:TimeInterval{
|
||
get{
|
||
if let times = UserDefaults.standard.object(forKey: "IntermediaryDuration") as? TimeInterval {
|
||
return times
|
||
}else {
|
||
return 40
|
||
}
|
||
}
|
||
}
|
||
///开屏中介记录时间值
|
||
private var intermediaryOpenShowTime:Date?
|
||
///插页中介记录时间值
|
||
private var intermediaryInterstitialShowTime:Date?
|
||
//中介间隔是否通过
|
||
private var isPassIntermediary:Bool = true
|
||
|
||
///设置插页总开关
|
||
func setInterstitialSwitch(_ status:Bool) {
|
||
interstitialSwitch = status
|
||
}
|
||
///获得插页开关的状态
|
||
func getInterstitialSwitch() -> Bool {
|
||
return interstitialSwitch
|
||
}
|
||
///设置插页广告间隔秒数
|
||
func setInterstitialDuration(_ duration:TimeInterval?) {
|
||
if let times = duration {
|
||
UserDefaults.standard.set(times, forKey: "InterstitialDuration")
|
||
}
|
||
}
|
||
///设置中介间隔秒数
|
||
func setIntermediaryDuration(_ duration:TimeInterval?) {
|
||
if let times = duration {
|
||
UserDefaults.standard.set(times, forKey: "IntermediaryDuration")
|
||
}
|
||
}
|
||
///是否达到插页间隔时长(达到即可继续展示插页广告)
|
||
private func isShowInterstitialADAvailable(_ date:Date) -> Bool {
|
||
return Date().timeIntervalSince(date) > interstitialDuration
|
||
}
|
||
private override init() {
|
||
super.init()
|
||
NotificationCenter.notificationKey.add(observer: self, selector: #selector(netWorkReachableAction(_:)), notificationName: .net_switch_reachable)
|
||
GADMobileAds.sharedInstance().audioVideoManager.delegate = self
|
||
// GADMobileAds.sharedInstance().audioVideoManager.
|
||
|
||
reloadAdMobIDs()
|
||
//对开屏广告完成处理闭包
|
||
completeOpenAdBlock = {
|
||
[weak self] in
|
||
guard let self = self, interstitialSwitch == true else {return}
|
||
//销毁现在的开屏广告实例
|
||
appOpenAd = nil
|
||
appInterstitialAd = nil
|
||
isShowingOpenAd = false
|
||
loadOpenAdTime = nil
|
||
//关闭插页广告开关
|
||
interstitialSwitch = false
|
||
//更新开屏广告中介间隔时间
|
||
intermediaryOpenShowTime = Date()
|
||
//重新加载后续的开屏广告
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
|
||
[weak self] in
|
||
self?.loadOpenAd(.HOST) { status in
|
||
if status == true {
|
||
print("新的开屏广告加载成功")
|
||
}else {
|
||
print("开屏广告加载失败了")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//搜索插页广告完成处理闭包
|
||
completeSearchInterstitialAdBlock = {
|
||
[weak self] in
|
||
guard let self = self, interstitialSwitch == true else {return}
|
||
//销毁现在的搜索插页广告实例
|
||
searchInterstitialAd = nil
|
||
isShowingSearchInterstitialAd = false
|
||
loadSearchInterstitialAdTime = nil
|
||
//关闭插页广告开关
|
||
interstitialSwitch = false
|
||
//更新插页广告中介间隔时长
|
||
intermediaryInterstitialShowTime = Date()
|
||
//重新加载后续的搜索插页广告
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||
[weak self] in
|
||
self?.loadSearchInterstitialAd { status in
|
||
if status {
|
||
print("成功加载搜索插页广告")
|
||
}else {
|
||
print("搜索插页广告加载失败")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//播放插页广告完成处理闭包
|
||
completePlayInterstitialAdBlock = {
|
||
[weak self] in
|
||
guard let self = self, interstitialSwitch == true else {return}
|
||
//销毁现在的播放插页广告实例
|
||
playInterstitialAd = nil
|
||
isShowingPlayInterstitialAd = false
|
||
loadPlayInterstitialAdTime = nil
|
||
//关闭插页广告开关
|
||
interstitialSwitch = false
|
||
//更新插页广告中介间隔时长
|
||
intermediaryInterstitialShowTime = Date()
|
||
//重新加载后续的播放插页广告
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||
[weak self] in
|
||
self?.loadPlayInterstitialAd { status in
|
||
if status {
|
||
print("成功加载播放插页广告")
|
||
}else {
|
||
print("播放插页广告加载失败")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//切歌插页
|
||
completeSwitchInterstitialAdBlock = {
|
||
[weak self] in
|
||
guard let self = self, interstitialSwitch == true else {return}
|
||
//销毁现在的切歌插页广告实例
|
||
switchInterstitialAd = nil
|
||
isShowingSwitchInterstitialAd = false
|
||
loadSwitchInterstitialAdTime = nil
|
||
//关闭插页广告开关
|
||
interstitialSwitch = false
|
||
//更新插页广告中介间隔时长
|
||
intermediaryInterstitialShowTime = Date()
|
||
//重新加载后续的切歌插页广告
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||
[weak self] in
|
||
self?.loadSwitchInterstitialAd { status in
|
||
if status {
|
||
print("成功加载切歌插页广告")
|
||
}else {
|
||
print("切歌插页广告加载失败")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//下载插页
|
||
completeLoadInterstitialAdBlock = {
|
||
[weak self] in
|
||
guard let self = self, interstitialSwitch == true else {return}
|
||
//销毁现在的切歌插页广告实例
|
||
loadInterstitialAd = nil
|
||
isShowingLoadInterstitialAd = false
|
||
loadLoadInterstitialAdTime = nil
|
||
//关闭插页广告开关
|
||
interstitialSwitch = false
|
||
//更新插页广告中介间隔时长
|
||
intermediaryInterstitialShowTime = Date()
|
||
//重新加载后续的下载插页广告
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||
[weak self] in
|
||
self?.loadLoadInterstitialAd { status in
|
||
if status {
|
||
print("成功加载下载插页广告")
|
||
}else {
|
||
print("下载插页广告加载失败")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//曲库插页广告完成处理闭包
|
||
completeLibraryInterstitialAdBlock = {
|
||
[weak self] in
|
||
guard let self = self, interstitialSwitch == true else {return}
|
||
//销毁现在的曲库插页广告实例
|
||
libraryInterstitialAd = nil
|
||
isShowingLibraryInterstitialAd = false
|
||
loadLibraryInterstitialAdTime = nil
|
||
//关闭插页广告开关
|
||
interstitialSwitch = false
|
||
//更新插页广告中介间隔时长
|
||
intermediaryInterstitialShowTime = Date()
|
||
//重新加载后续的曲库插页广告
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||
[weak self] in
|
||
self?.loadLibraryInterstitialAd { status in
|
||
if status {
|
||
print("成功加载曲库插页广告")
|
||
}else {
|
||
print("曲库插页广告加载失败")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//全局插页广告完成处理闭包
|
||
completeGlobalInterstitialAdBlock = {
|
||
[weak self] in
|
||
guard let self = self, interstitialSwitch == true else {return}
|
||
//销毁现在的全局插页广告实例
|
||
globalInterstitialAd = nil
|
||
isShowingGlobalInterstitialAd = false
|
||
loadGlobalInterstitialAdTime = nil
|
||
//关闭插页广告开关
|
||
interstitialSwitch = false
|
||
//更新插页广告中介间隔时长
|
||
intermediaryInterstitialShowTime = Date()
|
||
//重新加载后续的全局插页广告
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||
[weak self] in
|
||
self?.loadGlobalInterstitialAd { status in
|
||
if status {
|
||
print("成功加载全局插页广告")
|
||
}else {
|
||
print("全局插页广告加载失败")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///更新ID
|
||
func reloadAdMobIDs() {
|
||
//更新所有广告ID
|
||
if let data = UserDefaults.standard.object(forKey: "OpenICEID") as? Data, let array = jsonforCoreAdModel(data) {
|
||
print("成功提取ID")
|
||
OpenICEID = array.sorted(by: {$0.level > $1.level})
|
||
}
|
||
if let data = UserDefaults.standard.object(forKey: "OpenHOSTID") as? Data, let array = jsonforCoreAdModel(data) {
|
||
OpenHOSTID = array.sorted(by: {$0.level > $1.level})
|
||
}
|
||
if let data = UserDefaults.standard.object(forKey: "SearchINSERTID") as? Data, let array = jsonforCoreAdModel(data) {
|
||
SearchINSERTID = array.sorted(by: {$0.level > $1.level})
|
||
}
|
||
if let data = UserDefaults.standard.object(forKey: "SearchNATIVEID") as? Data, let array = jsonforCoreAdModel(data) {
|
||
SearchNATIVEID = array.sorted(by: {$0.level > $1.level})
|
||
}
|
||
if let data = UserDefaults.standard.object(forKey: "PlayerINSERTID") as? Data, let array = jsonforCoreAdModel(data) {
|
||
PlayerINSERTID = array.sorted(by: {$0.level > $1.level})
|
||
}
|
||
if let data = UserDefaults.standard.object(forKey: "SwitchINSERTID") as? Data, let array = jsonforCoreAdModel(data) {
|
||
SwitchINSERTID = array.sorted(by: {$0.level > $1.level})
|
||
}
|
||
if let data = UserDefaults.standard.object(forKey: "LoadINSERTID") as? Data, let array = jsonforCoreAdModel(data) {
|
||
LoadINSERTID = array.sorted(by: {$0.level > $1.level})
|
||
}
|
||
if let data = UserDefaults.standard.object(forKey: "LibraryINSERTID") as? Data, let array = jsonforCoreAdModel(data) {
|
||
LibraryINSERTID = array.sorted(by: {$0.level > $1.level})
|
||
}
|
||
if let data = UserDefaults.standard.object(forKey: "LibraryNATIVEID") as? Data, let array = jsonforCoreAdModel(data) {
|
||
LibraryNATIVEID = array.sorted(by: {$0.level > $1.level})
|
||
}
|
||
if let data = UserDefaults.standard.object(forKey: "GlobalINSERTID") as? Data, let array = jsonforCoreAdModel(data) {
|
||
GlobalINSERTID = array.sorted(by: {$0.level > $1.level})
|
||
}
|
||
}
|
||
///加载更多广告
|
||
func loadMoreAdMobs() {
|
||
loadPlayInterstitialAd{status in
|
||
if status {
|
||
print("成功加载播放插页广告")
|
||
}else {
|
||
print("播放插页广告加载失败")
|
||
}
|
||
}
|
||
loadSearchInterstitialAd { status in
|
||
if status {
|
||
print("成功加载搜索插页广告")
|
||
}else {
|
||
print("搜索插页广告加载失败")
|
||
}
|
||
}
|
||
loadLibraryInterstitialAd { status in
|
||
if status {
|
||
print("成功加载曲库插页广告")
|
||
}else {
|
||
print("曲库插页广告加载失败")
|
||
}
|
||
|
||
}
|
||
}
|
||
//网络可用时触发
|
||
@objc private func netWorkReachableAction(_ sender:Notification) {
|
||
DispatchQueue.main.async {
|
||
[weak self] in
|
||
guard let self = self else {return}
|
||
loadMoreAdMobs()
|
||
}
|
||
}
|
||
deinit{
|
||
NotificationCenter.default.removeObserver(self)
|
||
displaySearchTimer?.invalidate()
|
||
displaySearchTimer = nil
|
||
displayLibraryTimer?.invalidate()
|
||
displayLibraryTimer = nil
|
||
}
|
||
///开始缓存广告
|
||
func start() {
|
||
sharedInstance.start { status in
|
||
print("App启动,开始加载广告")
|
||
let adapterStatuses = status.adapterStatusesByClassName
|
||
for adapter in adapterStatuses {
|
||
let adapterStatus = adapter.value
|
||
print("Adapter Name: \(adapter.key), Description: \(adapterStatus.description), Latency: \(adapterStatus.latency)")
|
||
}
|
||
}
|
||
}
|
||
///检索与插页广告之间的中介间隔时长是否达标
|
||
private func retrieveIntermediaryInterstitial() -> Bool {
|
||
//判断插页中介记录时间值是否存在
|
||
guard let date = intermediaryInterstitialShowTime else {return true}
|
||
return Date().timeIntervalSince(date) > intermediaryDuration
|
||
}
|
||
///检索与开屏广告之间的中介间隔时长是否达标
|
||
private func retrieveIntermediaryOpen() -> Bool {
|
||
//判断插页中介记录时间值是否存在
|
||
guard let date = intermediaryOpenShowTime else {return true}
|
||
return Date().timeIntervalSince(date) > intermediaryDuration
|
||
}
|
||
//MARK: - 开屏
|
||
//开屏冷启动广告ID
|
||
private var OpenICEID:[MPPositive_AdItemModel] = []
|
||
//开屏热启动广告ID
|
||
private var OpenHOSTID:[MPPositive_AdItemModel] = []
|
||
//应用开屏广告实例
|
||
var appOpenAd:GADAppOpenAd?
|
||
//应用插页广告实例
|
||
var appInterstitialAd:GADInterstitialAd?
|
||
//是否正在加载广告
|
||
private var isLoadingOpenAd:Bool = false
|
||
//是否正在展示广告
|
||
var isShowingOpenAd:Bool = false
|
||
//开屏广告加载时间
|
||
private var loadOpenAdTime:Date?
|
||
//开屏广告时间间隔(默认10秒)
|
||
private var openAppDuration:TimeInterval{
|
||
get{
|
||
if let times = UserDefaults.standard.object(forKey: "OpenAppDuration") as? TimeInterval {
|
||
return times
|
||
}else {
|
||
return 10
|
||
}
|
||
}
|
||
}
|
||
//设置开屏广告时间间隔
|
||
func setOpenAppDuration(_ duration:TimeInterval) {
|
||
UserDefaults.standard.set(duration, forKey: "OpenAppDuration")
|
||
}
|
||
//获取开屏广告时间间隔
|
||
func getOpenAppDuration() -> TimeInterval {
|
||
return self.openAppDuration
|
||
}
|
||
//开屏广告加载完成处理闭包
|
||
var completeOpenAdBlock:(() -> Void)?
|
||
|
||
///异步加载开屏广告
|
||
func loadOpenAd(_ type:OpenType, level:Int = 0, completion: @escaping (Bool) -> Void) {
|
||
guard openAdStatus, internalAdStatus else {return}
|
||
// 检测当前是否有广告或者有广告正在加载
|
||
if isLoadingOpenAd || isOpenAdAvailable() {
|
||
// 有广告或有广告在加载
|
||
completion(false)
|
||
return
|
||
}
|
||
//检索是否超过了对应的id组的阶级数量
|
||
var item:MPPositive_AdItemModel
|
||
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)
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
|
||
[weak self] in
|
||
self?.loadOpenAd(.HOST, completion: { status in
|
||
if status {
|
||
print("重新加载热启动广告成功")
|
||
}else {
|
||
print("重新加载热启动广告失败")
|
||
}
|
||
})
|
||
}
|
||
return
|
||
}
|
||
item = OpenHOSTID[level]
|
||
}
|
||
isLoadingOpenAd = true
|
||
let request = GADRequest()
|
||
MP_ADSimpleManager.shared.isAdSounded()
|
||
//判断需要生成什么广告
|
||
if item.type == .Open {
|
||
//生成开屏广告
|
||
// 使用 GADAppOpenAd 的 load 方法和一个completion handler来加载广告
|
||
GADAppOpenAd.load(withAdUnitID: item.identifier, request: request) { ad, error in
|
||
DispatchQueue.main.async { [weak self] in
|
||
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 {
|
||
self.appOpenAd = ad
|
||
self.isLoadingOpenAd = false
|
||
//实现代理
|
||
self.appOpenAd?.fullScreenContentDelegate = self
|
||
//更新加载时间
|
||
self.loadOpenAdTime = Date()
|
||
completion(true)
|
||
}
|
||
}
|
||
}
|
||
}else if item.type == .Insert {
|
||
//生成插页广告
|
||
GADInterstitialAd.load(withAdUnitID: item.identifier, request: request ) { ad, error in
|
||
DispatchQueue.main.async { [weak self] in
|
||
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 {
|
||
self.appInterstitialAd = ad
|
||
self.isLoadingOpenAd = false
|
||
//实现代理
|
||
self.appInterstitialAd?.fullScreenContentDelegate = self
|
||
//更新加载时间
|
||
self.loadOpenAdTime = Date()
|
||
completion(true)
|
||
}
|
||
}
|
||
}
|
||
}else {
|
||
completion(false)
|
||
}
|
||
}
|
||
///开屏广告展示
|
||
func showOpenAdIfAvailable(_ type:OpenType, completion:((_ T:GADFullScreenPresentingAd, _ isOpen:Bool) -> Void)?) {
|
||
guard openAdStatus, internalAdStatus else {return}
|
||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||
guard !interstitialSwitch, !isShowingOpenAd, retrieveIntermediaryInterstitial() else { return }
|
||
// 如果应用开屏广告尚不可用但应该显示,则加载新广告。
|
||
if !isOpenAdAvailable() {
|
||
loadOpenAd(type) { [weak self] success in
|
||
guard let self = self else { return }
|
||
if success {
|
||
self.showOpenAdIfAvailable(type, completion: completion)
|
||
}
|
||
}
|
||
if type == .HOST {
|
||
//同步展示全屏广告
|
||
showGlobalInterstitialAdIfAvailable { ad in
|
||
if let ad = ad {
|
||
if let block = completion {
|
||
block(ad, false)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return
|
||
}
|
||
if type == .ICE {
|
||
MP_AnalyticsManager.shared.cold_ads_chanceAction()
|
||
}else {
|
||
MP_AnalyticsManager.shared.hot_ads_chanceAction()
|
||
}
|
||
//当开屏广告确定有值后展示
|
||
if let ad = (appOpenAd) {
|
||
//传递加载完成事件
|
||
if let block = completion {
|
||
block(ad, true)
|
||
}else {
|
||
isShowingOpenAd = true
|
||
interstitialSwitch = true
|
||
DispatchQueue.main.async {
|
||
[weak self] in
|
||
guard let self = self else {return}
|
||
do{
|
||
try ad.canPresent(fromRootViewController: nil)
|
||
ad.present(fromRootViewController: nil)
|
||
|
||
}catch{
|
||
print("开屏广告展示失败,失败原因:\(error)")
|
||
if completeOpenAdBlock != nil {
|
||
completeOpenAdBlock!()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}else if let ad = (appInterstitialAd) {
|
||
//传递加载完成事件
|
||
if let block = completion {
|
||
block(ad, false)
|
||
}else {
|
||
isShowingOpenAd = true
|
||
interstitialSwitch = true
|
||
DispatchQueue.main.async {
|
||
[weak self] in
|
||
guard let self = self else {return}
|
||
do{
|
||
try ad.canPresent(fromRootViewController: nil)
|
||
ad.present(fromRootViewController: nil)
|
||
}catch{
|
||
print("开屏广告展示失败,失败原因:\(error)")
|
||
if completeOpenAdBlock != nil {
|
||
completeOpenAdBlock!()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}else {
|
||
print("开屏广告展示失败")
|
||
if type == .ICE {
|
||
MP_AnalyticsManager.shared.cold_ads_showFailureAction("Ad loading failed")
|
||
}else {
|
||
MP_AnalyticsManager.shared.hot_ads_showFailureAction("Ad loading failed")
|
||
}
|
||
}
|
||
}
|
||
///查询是否有开屏广告
|
||
func isOpenAdAvailable() -> Bool {
|
||
return (appOpenAd != nil || appInterstitialAd != nil) && wasAdexpirationTime(loadOpenAdTime)
|
||
}
|
||
|
||
//MARK: - 搜索
|
||
//搜索插页广告ID
|
||
private var SearchINSERTID:[MPPositive_AdItemModel] = []
|
||
//搜索原生广告ID
|
||
private var SearchNATIVEID:[MPPositive_AdItemModel] = []
|
||
///搜索插页广告
|
||
private var searchInterstitialAd:GADInterstitialAd?
|
||
///是否正在加载搜索插页广告
|
||
private var isLoadingSearchInterstitialAd:Bool = false
|
||
///是否正在展示搜索插页广告
|
||
var isShowingSearchInterstitialAd:Bool = false
|
||
///搜索插页加载时间
|
||
private var loadSearchInterstitialAdTime:Date?
|
||
///搜索广告处理闭包
|
||
var completeSearchInterstitialAdBlock:(() -> Void)?
|
||
///搜索原生广告加载器
|
||
var searchAdLoader:GADAdLoader?
|
||
///搜索原生广告
|
||
var searchNativeAd:GADNativeAd?
|
||
///搜索原生广告视图
|
||
var searchNativeAdView:GADNativeAdView?
|
||
///搜索原生存储时长
|
||
var refreshSearchTimes:TimeInterval = 3600
|
||
///搜索原生显示刷新计时器
|
||
var displaySearchTimer:Timer?
|
||
///搜索原生加载时间
|
||
var expirationSearchDate:Date?
|
||
///搜索控制器
|
||
var searchViewController:UIViewController?
|
||
///搜索原生回调闭包
|
||
var onSearchNativeAdBlock:(() -> Void)?
|
||
///配置搜索原生广告加载器
|
||
func configureSreachNativeAd(rootController vc:UIViewController) {
|
||
searchViewController = vc
|
||
}
|
||
///搜索原生广告加载
|
||
func loadSearchNativeAd() {
|
||
guard openAdStatus, internalAdStatus else {return}
|
||
guard let vc = searchViewController else {return}
|
||
//请求数量限制器
|
||
let multipleAdOptions = GADMultipleAdsAdLoaderOptions()
|
||
//加载一条,每次即使结束后重新刷新数据
|
||
multipleAdOptions.numberOfAds = 1
|
||
//图片加载限制器
|
||
let imageAdOptions = GADNativeAdImageAdLoaderOptions()
|
||
imageAdOptions.shouldRequestMultipleImages = false
|
||
//视频加载限制器
|
||
let videoAdOptions = GADVideoOptions()
|
||
videoAdOptions.startMuted = true
|
||
if let first = SearchNATIVEID.first, first.type == .Native {
|
||
MP_AnalyticsManager.shared.result_ads_chanceAction()
|
||
searchAdLoader = GADAdLoader(adUnitID: first.identifier, rootViewController: vc, adTypes: [.native], options: [multipleAdOptions, imageAdOptions, videoAdOptions])
|
||
searchAdLoader?.delegate = self
|
||
let request = GADRequest()
|
||
searchAdLoader?.load(request)
|
||
}
|
||
}
|
||
///将加载的搜索原生广告添加到页面中
|
||
func layoutSearchNativeAd(in containerView: UIView) {
|
||
guard openAdStatus, internalAdStatus else {return}
|
||
MP_ADSimpleManager.shared.isAdMuted()
|
||
containerView.subviews.forEach { item in
|
||
item.removeFromSuperview()
|
||
}
|
||
searchNativeAdView = nil
|
||
//初始化广告模版对象
|
||
guard let templateView = (Bundle.main.loadNibNamed("GADTSmallTemplateView", owner: nil, options: nil)?.first as? GADTTemplateView), let nativeAd = searchNativeAd, refreshSearchDate(expirationSearchDate) else {
|
||
//重新加载
|
||
loadSearchNativeAd()
|
||
return
|
||
}
|
||
searchNativeAdView = templateView
|
||
nativeAd.delegate = self
|
||
containerView.addSubview(templateView)
|
||
templateView.snp.makeConstraints { make in
|
||
make.top.bottom.equalToSuperview()
|
||
make.left.equalToSuperview().offset(16*width)
|
||
make.right.equalToSuperview().offset(-16*width)
|
||
}
|
||
//创建一个choiveView
|
||
let customRect = CGRect(x: containerView.frame.width-(16*width)-25, y: 0, width: 25, height: 25)
|
||
let customAdChoicesView = GADAdChoicesView(frame: customRect)
|
||
templateView.addSubview(customAdChoicesView)
|
||
templateView.adChoicesView = customAdChoicesView
|
||
containerView.snp.updateConstraints { make in
|
||
make.height.equalTo(125)
|
||
}
|
||
templateView.nativeAd = nativeAd
|
||
nativeAd.paidEventHandler = { adValue in
|
||
MP_AnalyticsManager.shared.result_ads_showAction(nativeAd.responseInfo, adValue: adValue)
|
||
}
|
||
// 设置展示计时器,60 秒后刷新加载新广告
|
||
displaySearchTimer?.invalidate()
|
||
displaySearchTimer = Timer.scheduledTimer(withTimeInterval: 60, repeats: false) { [weak self] _ in
|
||
self?.loadSearchNativeAd()
|
||
}
|
||
}
|
||
///搜索原生存储时长
|
||
private func refreshSearchDate(_ date:Date?) -> Bool {
|
||
guard let date = date else {return false}
|
||
return Date().timeIntervalSince(date) < refreshSearchTimes
|
||
}
|
||
|
||
//异步加载搜索插页广告
|
||
func loadSearchInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) {
|
||
guard openAdStatus, internalAdStatus else {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")
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||
[weak self] in
|
||
self?.loadSearchInterstitialAd { status in
|
||
if status {
|
||
print("重新加载搜索插页广告")
|
||
}else {
|
||
print("加载搜索插页广告失败")
|
||
}
|
||
}
|
||
}
|
||
return
|
||
}
|
||
isLoadingSearchInterstitialAd = true
|
||
let item = SearchINSERTID[level]
|
||
let request = GADRequest()
|
||
MP_ADSimpleManager.shared.isAdSounded()
|
||
//加载搜索插页广告
|
||
GADInterstitialAd.load(withAdUnitID: item.identifier, request: request) { ad, error in
|
||
DispatchQueue.main.async { [weak self] in
|
||
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 {
|
||
self.searchInterstitialAd = ad
|
||
self.isLoadingSearchInterstitialAd = false
|
||
//实现代理
|
||
self.searchInterstitialAd?.fullScreenContentDelegate = self
|
||
//更新加载时间
|
||
self.loadSearchInterstitialAdTime = Date()
|
||
completion(true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///搜索插页广告展示
|
||
func showSearchInterstitialAdIfAvailable(completion:((GADInterstitialAd) -> Void)?) {
|
||
guard openAdStatus, internalAdStatus else {return}
|
||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||
guard !interstitialSwitch, !isShowingSearchInterstitialAd, retrieveIntermediaryOpen() else { return }
|
||
//检索是否存在插页间隔时间
|
||
if let date = interstitialDate {
|
||
if isShowInterstitialADAvailable(date) == false {
|
||
//未超过插页间隔时长
|
||
print("距上一次展示插页广告时长未超过要求,此次插页广告展示滞后")
|
||
return
|
||
}
|
||
}
|
||
// 如果搜索广告尚不可用但应该显示,则加载新广告。
|
||
if !isSearchInterstitialAdAvailable() {
|
||
loadSearchInterstitialAd { [weak self] success in
|
||
guard let self = self else { return }
|
||
if success {
|
||
self.showSearchInterstitialAdIfAvailable(completion: completion)
|
||
}
|
||
}
|
||
//展示全屏广告
|
||
showGlobalInterstitialAdIfAvailable(completion: nil)
|
||
return
|
||
}
|
||
MP_AnalyticsManager.shared.search_ads_chanceAction()
|
||
//当搜索插页广告确定有值后展示
|
||
if let ad = searchInterstitialAd {
|
||
//传递加载完成事件
|
||
if let block = completion {
|
||
block(ad)
|
||
}else {
|
||
isShowingSearchInterstitialAd = true
|
||
interstitialSwitch = true
|
||
ad.present(fromRootViewController: nil)
|
||
}
|
||
}else {
|
||
MP_AnalyticsManager.shared.search_ads_showFailureAction("Ad loading failed")
|
||
}
|
||
}
|
||
//查询是否有搜索插页广告
|
||
func isSearchInterstitialAdAvailable() -> Bool {
|
||
return searchInterstitialAd != nil && wasAdexpirationTime(loadSearchInterstitialAdTime)
|
||
}
|
||
|
||
//MARK: - 播放
|
||
//播放插页广告ID
|
||
private var PlayerINSERTID:[MPPositive_AdItemModel] = []
|
||
///播放插页广告
|
||
var playInterstitialAd:GADInterstitialAd?
|
||
///是否正在加载播放插页广告
|
||
private var isLoadingPlayInterstitialAd:Bool = false
|
||
///是否正在展示播放插页广告
|
||
var isShowingPlayInterstitialAd:Bool = false
|
||
///播放插页加载时间
|
||
private var loadPlayInterstitialAdTime:Date?
|
||
///播放广告处理闭包
|
||
var completePlayInterstitialAdBlock:(() -> Void)?
|
||
//异步加载播放插页广告
|
||
func loadPlayInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) {
|
||
guard openAdStatus, internalAdStatus else {
|
||
completion(false)
|
||
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")
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||
[weak self] in
|
||
self?.loadPlayInterstitialAd { status in
|
||
if status {
|
||
print("重新加载播放插页广告")
|
||
}else {
|
||
print("加载播放插页广告失败")
|
||
}
|
||
}
|
||
}
|
||
return
|
||
}
|
||
isLoadingPlayInterstitialAd = true
|
||
let item = PlayerINSERTID[level]
|
||
let request = GADRequest()
|
||
MP_ADSimpleManager.shared.isAdSounded()
|
||
//加载播放插页广告
|
||
GADInterstitialAd.load(withAdUnitID: item.identifier, request: request) { ad, error in
|
||
DispatchQueue.main.async { [weak self] in
|
||
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 {
|
||
self.playInterstitialAd = ad
|
||
self.isLoadingPlayInterstitialAd = false
|
||
//实现代理
|
||
self.playInterstitialAd?.fullScreenContentDelegate = self
|
||
//更新加载时间
|
||
self.loadPlayInterstitialAdTime = Date()
|
||
completion(true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///播放插页广告展示
|
||
func showPlayInterstitialAdIfAvailable(completion:((GADInterstitialAd?) -> Void)?) {
|
||
guard openAdStatus, internalAdStatus else {
|
||
completion?(nil)
|
||
return
|
||
}
|
||
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
|
||
completion?(nil)
|
||
return
|
||
}
|
||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||
guard !interstitialSwitch, !isShowingPlayInterstitialAd, retrieveIntermediaryOpen() else {
|
||
completion?(nil)
|
||
return
|
||
}
|
||
//检索是否存在插页间隔时间
|
||
if let date = interstitialDate {
|
||
if isShowInterstitialADAvailable(date) == false {
|
||
//未超过插页间隔时长
|
||
print("距上一次展示插页广告时长未超过要求,此次插页广告展示滞后")
|
||
completion?(nil)
|
||
return
|
||
}
|
||
}
|
||
// 如果播放插页广告尚不可用但应该显示,则加载新广告。
|
||
if !isPlayInterstitialAdAvailable() {
|
||
loadPlayInterstitialAd{ [weak self] success in
|
||
guard let self = self else { return }
|
||
if success {
|
||
print("播放广告已加载")
|
||
}
|
||
}
|
||
completion?(nil)
|
||
return
|
||
}
|
||
MP_AnalyticsManager.shared.play_ads_chanceAction()
|
||
//当播放插页广告确定有值后展示
|
||
if let ad = playInterstitialAd {
|
||
//传递加载完成事件
|
||
if let block = completion {
|
||
block(ad)
|
||
}else {
|
||
isShowingPlayInterstitialAd = true
|
||
interstitialSwitch = true
|
||
ad.present(fromRootViewController: nil)
|
||
}
|
||
}else {
|
||
MP_AnalyticsManager.shared.play_ads_showFailureAction("Ad loading failed")
|
||
completion?(nil)
|
||
}
|
||
}
|
||
//查询是否有播放插页广告
|
||
func isPlayInterstitialAdAvailable() -> Bool {
|
||
return playInterstitialAd != nil && wasAdexpirationTime(loadPlayInterstitialAdTime)
|
||
}
|
||
|
||
|
||
//MARK: - 切歌
|
||
//切歌插页广告ID
|
||
private var SwitchINSERTID:[MPPositive_AdItemModel] = []
|
||
///切歌插页广告
|
||
var switchInterstitialAd:GADInterstitialAd?
|
||
///是否正在加载切歌插页广告
|
||
private var isLoadingSwitchInterstitialAd:Bool = false
|
||
///是否正在展示切歌插页广告
|
||
var isShowingSwitchInterstitialAd:Bool = false
|
||
///切歌插页加载时间
|
||
private var loadSwitchInterstitialAdTime:Date?
|
||
///切歌广告处理闭包
|
||
var completeSwitchInterstitialAdBlock:(() -> Void)?
|
||
//异步加载切歌插页广告
|
||
func loadSwitchInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) {
|
||
guard openAdStatus, internalAdStatus else {
|
||
completion(false)
|
||
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")
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||
[weak self] in
|
||
self?.loadSwitchInterstitialAd { status in
|
||
if status {
|
||
print("重新加载切歌插页广告")
|
||
}else {
|
||
print("加载切歌插页广告失败")
|
||
}
|
||
}
|
||
}
|
||
return
|
||
}
|
||
isLoadingSwitchInterstitialAd = true
|
||
let item = SwitchINSERTID[level]
|
||
let request = GADRequest()
|
||
//加载播放插页广告
|
||
GADInterstitialAd.load(withAdUnitID: item.identifier, request: request) { ad, error in
|
||
DispatchQueue.main.async { [weak self] in
|
||
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 {
|
||
self.switchInterstitialAd = ad
|
||
self.isLoadingSwitchInterstitialAd = false
|
||
//实现代理
|
||
self.switchInterstitialAd?.fullScreenContentDelegate = self
|
||
//更新加载时间
|
||
self.loadSwitchInterstitialAdTime = Date()
|
||
completion(true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///切歌插页广告展示
|
||
func showSwitchInterstitialAdIfAvailable(completion:((GADInterstitialAd) -> Void)?) {
|
||
guard openAdStatus, internalAdStatus else {
|
||
return
|
||
}
|
||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||
guard !interstitialSwitch, !isShowingSwitchInterstitialAd, retrieveIntermediaryOpen() else { return }
|
||
//检索是否存在插页间隔时间
|
||
if let date = interstitialDate {
|
||
if isShowInterstitialADAvailable(date) == false {
|
||
//未超过插页间隔时长
|
||
print("距上一次展示插页广告时长未超过要求,此次插页广告展示滞后")
|
||
return
|
||
}
|
||
}
|
||
// 如果切歌插页广告尚不可用但应该显示,则加载新广告。
|
||
if !isSwitchInterstitialAdAvailable() {
|
||
loadSwitchInterstitialAd{ [weak self] success in
|
||
guard let self = self else { return }
|
||
if success {
|
||
self.showSwitchInterstitialAdIfAvailable(completion: completion)
|
||
}
|
||
}
|
||
//展示全屏广告
|
||
showGlobalInterstitialAdIfAvailable(completion: nil)
|
||
return
|
||
}
|
||
MP_AnalyticsManager.shared.cut_ads_chanceAction()
|
||
//当切歌插页广告确定有值后展示
|
||
if let ad = switchInterstitialAd {
|
||
//传递加载完成事件
|
||
if let block = completion {
|
||
block(ad)
|
||
}else {
|
||
isShowingSwitchInterstitialAd = true
|
||
interstitialSwitch = true
|
||
ad.present(fromRootViewController: nil)
|
||
}
|
||
}else {
|
||
MP_AnalyticsManager.shared.cut_ads_showFailureAction("Ad loading failed")
|
||
}
|
||
}
|
||
//查询是否有切歌插页广告
|
||
func isSwitchInterstitialAdAvailable() -> Bool {
|
||
return switchInterstitialAd != nil && wasAdexpirationTime(loadSwitchInterstitialAdTime)
|
||
}
|
||
|
||
//MARK: - 下载
|
||
//下载插页广告ID
|
||
private var LoadINSERTID:[MPPositive_AdItemModel] = []
|
||
///下载插页广告
|
||
var loadInterstitialAd:GADInterstitialAd?
|
||
///是否正在加载下载插页广告
|
||
private var isLoadingLoadInterstitialAd:Bool = false
|
||
///是否正在展示下载插页广告
|
||
var isShowingLoadInterstitialAd:Bool = false
|
||
///下载插页加载时间
|
||
private var loadLoadInterstitialAdTime:Date?
|
||
///下载广告处理闭包
|
||
var completeLoadInterstitialAdBlock:(() -> Void)?
|
||
//异步加载下载插页广告
|
||
func loadLoadInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) {
|
||
guard openAdStatus, internalAdStatus else {
|
||
completion(false)
|
||
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")
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||
[weak self] in
|
||
self?.loadLoadInterstitialAd { status in
|
||
if status {
|
||
print("重新加载下载插页广告")
|
||
}else {
|
||
print("加载下载插页广告失败")
|
||
}
|
||
}
|
||
}
|
||
return
|
||
}
|
||
isLoadingLoadInterstitialAd = true
|
||
let item = LoadINSERTID[level]
|
||
let request = GADRequest()
|
||
//加载下载插页广告
|
||
GADInterstitialAd.load(withAdUnitID: item.identifier, request: request) { ad, error in
|
||
DispatchQueue.main.async { [weak self] in
|
||
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 {
|
||
self.loadInterstitialAd = ad
|
||
self.isLoadingLoadInterstitialAd = false
|
||
//实现代理
|
||
self.loadInterstitialAd?.fullScreenContentDelegate = self
|
||
//更新加载时间
|
||
self.loadLoadInterstitialAdTime = Date()
|
||
completion(true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///下载插页广告展示
|
||
func showLoadInterstitialAdIfAvailable(completion:((GADInterstitialAd) -> Void)?) {
|
||
guard openAdStatus, internalAdStatus else {
|
||
return
|
||
}
|
||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||
guard !interstitialSwitch, !isShowingLoadInterstitialAd, retrieveIntermediaryOpen() else { return }
|
||
//检索是否存在插页间隔时间
|
||
if let date = interstitialDate {
|
||
if isShowInterstitialADAvailable(date) == false {
|
||
//未超过插页间隔时长
|
||
print("距上一次展示插页广告时长未超过要求,此次插页广告展示滞后")
|
||
return
|
||
}
|
||
}
|
||
// 如果下载插页广告尚不可用但应该显示,则加载新广告。
|
||
if !isLoadInterstitialAdAvailable() {
|
||
loadLoadInterstitialAd{ [weak self] success in
|
||
guard let self = self else { return }
|
||
if success {
|
||
self.showLoadInterstitialAdIfAvailable(completion: completion)
|
||
}
|
||
}
|
||
//展示全屏广告
|
||
showGlobalInterstitialAdIfAvailable(completion: nil)
|
||
return
|
||
}
|
||
MP_AnalyticsManager.shared.dl_ads_chanceAction()
|
||
//当下载插页广告确定有值后展示
|
||
if let ad = loadInterstitialAd {
|
||
//传递加载完成事件
|
||
if let block = completion {
|
||
block(ad)
|
||
}else {
|
||
isShowingLoadInterstitialAd = true
|
||
interstitialSwitch = true
|
||
ad.present(fromRootViewController: nil)
|
||
}
|
||
}else {
|
||
MP_AnalyticsManager.shared.dl_ads_showFailureAction("Ad loading failed")
|
||
}
|
||
}
|
||
//查询是否有下载插页广告
|
||
func isLoadInterstitialAdAvailable() -> Bool {
|
||
return loadInterstitialAd != nil && wasAdexpirationTime(loadLoadInterstitialAdTime)
|
||
}
|
||
//MARK: - 曲库
|
||
//曲库插页ID
|
||
private var LibraryINSERTID:[MPPositive_AdItemModel] = []
|
||
//曲库原生ID
|
||
private var LibraryNATIVEID:[MPPositive_AdItemModel] = []
|
||
///曲库插页广告
|
||
private var libraryInterstitialAd:GADInterstitialAd?
|
||
///是否正在加载曲库插页广告
|
||
private var isLoadingLibraryInterstitialAd:Bool = false
|
||
///是否正在展示曲库插页广告
|
||
var isShowingLibraryInterstitialAd:Bool = false
|
||
///曲库插页加载时间
|
||
private var loadLibraryInterstitialAdTime:Date?
|
||
///曲库广告处理闭包
|
||
var completeLibraryInterstitialAdBlock:(() -> Void)?
|
||
///曲库原生广告加载器
|
||
var libraryAdLoader:GADAdLoader?
|
||
///曲库原生广告
|
||
var libraryNativeAds:[GADNativeAd]?
|
||
///曲库原生广告视图一
|
||
var libraryNativeAdFirstView:GADNativeAdView?
|
||
///原生广告视图二
|
||
var libraryNativeAdSecondView:GADNativeAdView?
|
||
///曲库原生存储时长
|
||
var refreshLibraryTimes:TimeInterval = 3600
|
||
///曲库原生显示刷新计时器
|
||
var displayLibraryTimer:Timer?
|
||
///曲库原生加载时间
|
||
var expirationLibraryDate:Date?
|
||
///曲库控制器
|
||
var libraryViewController:UIViewController?
|
||
///曲库原生回调闭包
|
||
var onLibraryNativeAdBlock:(() -> Void)?
|
||
///配置曲库原生广告加载器
|
||
func configureLibraryNativeAd(rootController vc:UIViewController) {
|
||
guard openAdStatus, internalAdStatus else {
|
||
return
|
||
}
|
||
if libraryViewController == nil {
|
||
libraryViewController = vc
|
||
}
|
||
}
|
||
///曲库原生广告加载
|
||
func loadLibraryNativeAd() {
|
||
guard openAdStatus, internalAdStatus else {return}
|
||
guard let vc = libraryViewController, libraryNativeAds == nil else {return}
|
||
//请求数量限制器
|
||
let multipleAdOptions = GADMultipleAdsAdLoaderOptions()
|
||
//加载一条,每次即使结束后重新刷新数据
|
||
multipleAdOptions.numberOfAds = 2
|
||
//图片加载限制器
|
||
let imageAdOptions = GADNativeAdImageAdLoaderOptions()
|
||
imageAdOptions.shouldRequestMultipleImages = false
|
||
//视频加载限制器
|
||
let videoAdOptions = GADVideoOptions()
|
||
videoAdOptions.startMuted = true
|
||
if let first = LibraryNATIVEID.first, first.type == .Native {
|
||
libraryAdLoader = GADAdLoader(adUnitID: first.identifier, rootViewController: vc, adTypes: [.native], options: [multipleAdOptions,imageAdOptions,videoAdOptions])
|
||
libraryAdLoader?.delegate = self
|
||
let request = GADRequest()
|
||
//设置不同广告中介器限制-Mintegral,Pangle,Liftoff,ironsource静音
|
||
libraryAdLoader?.load(request)
|
||
libraryNativeAds = []
|
||
}
|
||
}
|
||
///将加载的曲库原生广告添加到页面中
|
||
func layoutLibraryNativeAd(in containerView: UIView, index:Int, completion:(() -> Void)? = nil) {
|
||
guard openAdStatus, internalAdStatus else {return}
|
||
MP_ADSimpleManager.shared.isAdMuted()
|
||
containerView.subviews.forEach { item in
|
||
item.removeFromSuperview()
|
||
}
|
||
if index == 0 {
|
||
MP_AnalyticsManager.shared.lbr_ads_chanceAction()
|
||
//曲库第一页
|
||
libraryNativeAdFirstView = nil
|
||
//初始化广告模版对象
|
||
guard let templateView = (Bundle.main.loadNibNamed("GADTSmallTemplateView", owner: nil, options: nil)?.first as? GADTTemplateView), let nativeAds = libraryNativeAds, nativeAds.count == 2, let nativeAd = nativeAds.first, refreshLibraryDate(expirationLibraryDate) else {
|
||
//重新加载
|
||
loadLibraryNativeAd()
|
||
return
|
||
}
|
||
libraryNativeAdFirstView = templateView
|
||
nativeAd.delegate = self
|
||
containerView.addSubview(templateView)
|
||
templateView.snp.makeConstraints { make in
|
||
make.top.bottom.equalToSuperview()
|
||
make.left.equalToSuperview().offset(16*width)
|
||
make.right.equalToSuperview().offset(-16*width)
|
||
}
|
||
//创建一个choiveView
|
||
let customRect = CGRect(x: containerView.frame.width-(16*width)-25, y: 0, width: 25, height: 25)
|
||
let customAdChoicesView = GADAdChoicesView(frame: customRect)
|
||
templateView.addSubview(customAdChoicesView)
|
||
templateView.adChoicesView = customAdChoicesView
|
||
templateView.nativeAd = nativeAd
|
||
nativeAd.paidEventHandler = { adValue in
|
||
MP_AnalyticsManager.shared.lbr_ads_showAction(nativeAd.responseInfo, adValue: adValue)
|
||
}
|
||
}else {
|
||
MP_AnalyticsManager.shared.list_ads_chanceAction()
|
||
//曲库第二页
|
||
libraryNativeAdSecondView = nil
|
||
//初始化广告模版对象
|
||
guard let templateView = (Bundle.main.loadNibNamed("GADTSmallTemplateView", owner: nil, options: nil)?.first as? GADTTemplateView), let nativeAds = libraryNativeAds, nativeAds.count == 2, let nativeAd = nativeAds.last, refreshLibraryDate(expirationLibraryDate) else {
|
||
//重新加载
|
||
loadLibraryNativeAd()
|
||
return
|
||
}
|
||
libraryNativeAdSecondView = templateView
|
||
nativeAd.delegate = self
|
||
containerView.addSubview(templateView)
|
||
templateView.snp.makeConstraints { make in
|
||
make.top.bottom.equalToSuperview()
|
||
make.left.equalToSuperview().offset(16*width)
|
||
make.right.equalToSuperview().offset(-16*width)
|
||
}
|
||
//创建一个choiveView
|
||
let customRect = CGRect(x: containerView.frame.width-(16*width)-25, y: 0, width: 25, height: 25)
|
||
let customAdChoicesView = GADAdChoicesView(frame: customRect)
|
||
templateView.addSubview(customAdChoicesView)
|
||
templateView.adChoicesView = customAdChoicesView
|
||
templateView.nativeAd = nativeAd
|
||
nativeAd.paidEventHandler = { adValue in
|
||
MP_AnalyticsManager.shared.list_ads_showAction(nativeAd.responseInfo, adValue: adValue)
|
||
}
|
||
}
|
||
DispatchQueue.main.async {
|
||
[weak self] in
|
||
containerView.snp.updateConstraints { make in
|
||
make.height.equalTo(125)
|
||
}
|
||
completion?()
|
||
}
|
||
// 设置展示计时器,60 秒后刷新加载新广告
|
||
displayLibraryTimer?.invalidate()
|
||
displayLibraryTimer = Timer.scheduledTimer(withTimeInterval: 60, repeats: false) { [weak self] _ in
|
||
self?.loadLibraryNativeAd()
|
||
}
|
||
}
|
||
///曲库原生存储时长
|
||
private func refreshLibraryDate(_ date:Date?) -> Bool {
|
||
guard let date = date else {return false}
|
||
return Date().timeIntervalSince(date) < refreshLibraryTimes
|
||
}
|
||
//异步加载曲库插页广告
|
||
func loadLibraryInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) {
|
||
guard openAdStatus, internalAdStatus else {
|
||
completion(false)
|
||
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")
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||
[weak self] in
|
||
self?.loadLibraryInterstitialAd { status in
|
||
if status {
|
||
print("重新加载曲库插页广告")
|
||
}else {
|
||
print("加载曲库插页广告失败")
|
||
}
|
||
}
|
||
}
|
||
return
|
||
}
|
||
isLoadingLibraryInterstitialAd = true
|
||
let item = LibraryINSERTID[level]
|
||
let request = GADRequest()
|
||
MP_ADSimpleManager.shared.isAdSounded()
|
||
//加载曲库插页广告
|
||
GADInterstitialAd.load(withAdUnitID: item.identifier, request: request) { ad, error in
|
||
DispatchQueue.main.async { [weak self] in
|
||
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 {
|
||
self.libraryInterstitialAd = ad
|
||
self.isLoadingLibraryInterstitialAd = false
|
||
//实现代理
|
||
self.libraryInterstitialAd?.fullScreenContentDelegate = self
|
||
//更新加载时间
|
||
self.loadLibraryInterstitialAdTime = Date()
|
||
completion(true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///曲库插页广告展示
|
||
func showLibraryInterstitialAdIfAvailable(completion:((GADInterstitialAd) -> Void)?) {
|
||
guard openAdStatus, internalAdStatus else {
|
||
return
|
||
}
|
||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||
guard !interstitialSwitch, !isShowingLibraryInterstitialAd, retrieveIntermediaryOpen() else { return }
|
||
//检索是否存在插页间隔时间
|
||
if let date = interstitialDate {
|
||
if isShowInterstitialADAvailable(date) == false {
|
||
//未超过插页间隔时长
|
||
print("距上一次展示插页广告时长未超过要求,此次插页广告展示滞后")
|
||
return
|
||
}
|
||
}
|
||
// 如果曲库广告尚不可用但应该显示,则加载新广告。
|
||
if !isLibraryInterstitialAdAvailable() {
|
||
loadLibraryInterstitialAd { [weak self] success in
|
||
guard let self = self else { return }
|
||
if success {
|
||
self.showLibraryInterstitialAdIfAvailable(completion: completion)
|
||
}
|
||
}
|
||
//展示全屏广告
|
||
showGlobalInterstitialAdIfAvailable(completion: nil)
|
||
return
|
||
}
|
||
MP_AnalyticsManager.shared.listclk_ads_chanceAction()
|
||
//当曲库插页广告确定有值后展示
|
||
if let ad = libraryInterstitialAd {
|
||
|
||
//传递加载完成事件
|
||
if let block = completion {
|
||
block(ad)
|
||
}else {
|
||
isShowingLibraryInterstitialAd = true
|
||
interstitialSwitch = true
|
||
ad.present(fromRootViewController: nil)
|
||
}
|
||
}else {
|
||
MP_AnalyticsManager.shared.listclk_ads_showFailureAction("Ad loading failed")
|
||
}
|
||
}
|
||
//查询是否有曲库插页广告
|
||
func isLibraryInterstitialAdAvailable() -> Bool {
|
||
return libraryInterstitialAd != nil && wasAdexpirationTime(loadLibraryInterstitialAdTime)
|
||
}
|
||
|
||
|
||
//MARK: - 全局
|
||
//全局备用插页ID
|
||
private var GlobalINSERTID:[MPPositive_AdItemModel] = []
|
||
///全局插页广告
|
||
private var globalInterstitialAd:GADInterstitialAd?
|
||
///是否正在加载全局插页广告
|
||
private var isLoadingGlobalInterstitialAd:Bool = false
|
||
///是否正在展示全局插页广告
|
||
var isShowingGlobalInterstitialAd:Bool = false
|
||
///全局插页加载时间
|
||
private var loadGlobalInterstitialAdTime:Date?
|
||
///全局广告处理闭包
|
||
var completeGlobalInterstitialAdBlock:(() -> Void)?
|
||
//异步加载全局插页广告
|
||
func loadGlobalInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) {
|
||
guard openAdStatus, internalAdStatus else {
|
||
return
|
||
}
|
||
// 检测当前是否有广告或者有广告正在加载
|
||
if isLoadingGlobalInterstitialAd || isGlobalInterstitialAdAvailable() {
|
||
// 有广告或有广告在加载
|
||
completion(false)
|
||
return
|
||
}
|
||
guard level < (GlobalINSERTID.count) else {
|
||
print("全局插页广告组已经全部加载失败,停止继续加载")
|
||
completion(false)
|
||
return
|
||
}
|
||
isLoadingGlobalInterstitialAd = true
|
||
let item = GlobalINSERTID[level]
|
||
let request = GADRequest()
|
||
//设置不同广告中介器限制-Mintegral,Pangle,Liftoff,ironsource静音
|
||
// let mintegralExtra = GADMAdapterMintegralExtras()
|
||
// mintegralExtra.muteVideoAudio = true
|
||
// let appLovinExtra = GADMAdapterAppLovinExtras()
|
||
// appLovinExtra.muteAudio = true
|
||
// request.register(appLovinExtra)
|
||
// request.register(mintegralExtra)
|
||
//加载全局插页广告
|
||
GADInterstitialAd.load(withAdUnitID: item.identifier, request: request) { ad, error in
|
||
DispatchQueue.main.async { [weak self] in
|
||
guard let self = self else { return }
|
||
if let error = error {
|
||
print("加载全局插页广告失败,失败原因: \(error.localizedDescription),已下调广告ID等级,重新加载")
|
||
self.isLoadingGlobalInterstitialAd = false
|
||
loadGlobalInterstitialAd(level+1, completion: completion)
|
||
} else {
|
||
self.globalInterstitialAd = ad
|
||
self.isLoadingGlobalInterstitialAd = false
|
||
//实现代理
|
||
self.globalInterstitialAd?.fullScreenContentDelegate = self
|
||
//更新加载时间
|
||
self.loadGlobalInterstitialAdTime = Date()
|
||
completion(true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///全局插页广告展示
|
||
func showGlobalInterstitialAdIfAvailable(completion:((GADInterstitialAd?) -> Void)?) {
|
||
guard openAdStatus, internalAdStatus else {
|
||
return
|
||
}
|
||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||
guard !interstitialSwitch, !isShowingGlobalInterstitialAd, retrieveIntermediaryOpen() else { return }
|
||
//检索是否存在插页间隔时间
|
||
if let date = interstitialDate {
|
||
if isShowInterstitialADAvailable(date) == false {
|
||
//未超过插页间隔时长
|
||
print("距上一次展示插页广告时长未超过要求,此次插页广告展示滞后")
|
||
return
|
||
}
|
||
}
|
||
// 如果全局广告尚不可用但应该显示,则加载新广告。
|
||
if !isGlobalInterstitialAdAvailable() {
|
||
loadGlobalInterstitialAd { [weak self] success in
|
||
guard let self = self else { return }
|
||
if success {
|
||
self.showGlobalInterstitialAdIfAvailable(completion: completion)
|
||
}else {
|
||
completion?(nil)
|
||
}
|
||
}
|
||
return
|
||
}
|
||
//当全局插页广告确定有值后展示
|
||
if let ad = globalInterstitialAd {
|
||
//传递加载完成事件
|
||
if let block = completion {
|
||
block(ad)
|
||
}else {
|
||
isShowingGlobalInterstitialAd = true
|
||
interstitialSwitch = true
|
||
ad.present(fromRootViewController: nil)
|
||
}
|
||
}
|
||
}
|
||
//查询是否有全局插页广告
|
||
func isGlobalInterstitialAdAvailable() -> Bool {
|
||
return globalInterstitialAd != nil && wasAdexpirationTime(loadGlobalInterstitialAdTime)
|
||
}
|
||
//MARK: - 广告音频代理 GADAudioVideoManagerDelegate
|
||
//广告将会播放视频
|
||
func audioVideoManagerWillPlayVideo(_ audioVideoManager: GADAudioVideoManager) {
|
||
print("广告将会播放视频")
|
||
}
|
||
//广告将会暂停播放所有视频
|
||
func audioVideoManagerDidPauseAllVideo(_ audioVideoManager: GADAudioVideoManager) {
|
||
print("广告暂停播放视频")
|
||
}
|
||
//广告将要播放音频
|
||
func audioVideoManagerWillPlayAudio(_ audioVideoManager: GADAudioVideoManager) {
|
||
accessAppdelegate.setAudioActive()
|
||
}
|
||
//广告停止播放音频
|
||
func audioVideoManagerDidStopPlayingAudio(_ audioVideoManager: GADAudioVideoManager) {
|
||
DispatchQueue.main.asyncAfter(deadline: .now()+0.1) {
|
||
accessAppdelegate.setAudioActive()
|
||
}
|
||
}
|
||
//MARK: - 覆盖型广告代理 GADFullScreenContentDelegate
|
||
//覆盖型广告将要将要展示
|
||
func adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) {
|
||
if ad === appOpenAd || ad === appInterstitialAd {//开屏广告
|
||
print("当前展示的广告是开屏广告,广告ID--\(appOpenAd != nil ? (appOpenAd?.adUnitID ?? ""):(appInterstitialAd?.adUnitID ?? ""))")
|
||
//当前是热启动还是冷启动
|
||
if OpenICEID.contains(where: {($0.identifier == (appOpenAd?.adUnitID ?? "") || $0.identifier == (appInterstitialAd?.adUnitID ?? ""))}) {
|
||
//冷启动,检索是插页还是开屏
|
||
if let openAd = appOpenAd {
|
||
if MP_AnalyticsManager.shared.infoFromAdMobSource(openAd.responseInfo) {
|
||
//上传广告收益
|
||
openAd.paidEventHandler = { adValue in
|
||
MP_AnalyticsManager.shared.cold_ads_showSuccessAction(openAd.responseInfo, adValue: adValue)
|
||
}
|
||
}else {
|
||
MP_AnalyticsManager.shared.cold_ads_showSuccessAction(openAd.responseInfo, adValue: .init())
|
||
}
|
||
}else if let openAd = appInterstitialAd {
|
||
if MP_AnalyticsManager.shared.infoFromAdMobSource(openAd.responseInfo) {
|
||
//上传广告收益
|
||
openAd.paidEventHandler = { adValue in
|
||
MP_AnalyticsManager.shared.cold_ads_showSuccessAction(openAd.responseInfo, adValue: adValue)
|
||
}
|
||
}else {
|
||
MP_AnalyticsManager.shared.cold_ads_showSuccessAction(openAd.responseInfo, adValue: .init())
|
||
}
|
||
}
|
||
}else if OpenHOSTID.contains(where: {($0.identifier == (appOpenAd?.adUnitID ?? "") || $0.identifier == (appInterstitialAd?.adUnitID ?? ""))}) {
|
||
//热启动,检索是插页还是开屏
|
||
if let openAd = appOpenAd {
|
||
if MP_AnalyticsManager.shared.infoFromAdMobSource(openAd.responseInfo) {
|
||
//上传广告收益
|
||
openAd.paidEventHandler = { adValue in
|
||
MP_AnalyticsManager.shared.hot_ads_showSuccessAction(openAd.responseInfo, adValue: adValue)
|
||
}
|
||
}else {
|
||
MP_AnalyticsManager.shared.hot_ads_showSuccessAction(openAd.responseInfo, adValue: .init())
|
||
}
|
||
}else if let openAd = appInterstitialAd {
|
||
if MP_AnalyticsManager.shared.infoFromAdMobSource(openAd.responseInfo) {
|
||
//上传广告收益
|
||
openAd.paidEventHandler = { adValue in
|
||
MP_AnalyticsManager.shared.hot_ads_showSuccessAction(openAd.responseInfo, adValue: adValue)
|
||
}
|
||
}else {
|
||
MP_AnalyticsManager.shared.hot_ads_showSuccessAction(openAd.responseInfo, adValue: .init())
|
||
}
|
||
}
|
||
}
|
||
}else if ad === searchInterstitialAd {//搜索插页广告
|
||
print("当前展示的广告是搜索插页广告,广告ID--\(searchInterstitialAd?.adUnitID ?? "")")
|
||
if MP_AnalyticsManager.shared.infoFromAdMobSource(searchInterstitialAd?.responseInfo) {
|
||
searchInterstitialAd?.paidEventHandler = { adValue in
|
||
if let response = self.searchInterstitialAd?.responseInfo {
|
||
MP_AnalyticsManager.shared.search_ads_showSuccessAction(response, adValue: adValue)
|
||
}
|
||
}
|
||
}else {
|
||
if let response = self.searchInterstitialAd?.responseInfo {
|
||
MP_AnalyticsManager.shared.search_ads_showSuccessAction(response, adValue: .init())
|
||
}
|
||
}
|
||
}else if ad === playInterstitialAd {//播放插页广告
|
||
print("当前展示的广告是播放插页广告,广告ID--\(playInterstitialAd?.adUnitID ?? "")")
|
||
if MP_AnalyticsManager.shared.infoFromAdMobSource(playInterstitialAd?.responseInfo) {
|
||
playInterstitialAd?.paidEventHandler = { adValue in
|
||
if let response = self.playInterstitialAd?.responseInfo {
|
||
MP_AnalyticsManager.shared.play_ads_showSuccessAction(response, adValue: adValue)
|
||
}
|
||
}
|
||
}else {
|
||
if let response = self.playInterstitialAd?.responseInfo {
|
||
MP_AnalyticsManager.shared.play_ads_showSuccessAction(response, adValue: .init())
|
||
}
|
||
}
|
||
}else if ad === switchInterstitialAd {//切歌插页广告
|
||
print("当前展示的广告是切歌插页广告,广告ID--\(switchInterstitialAd?.adUnitID ?? "")")
|
||
if MP_AnalyticsManager.shared.infoFromAdMobSource(switchInterstitialAd?.responseInfo) {
|
||
switchInterstitialAd?.paidEventHandler = { adValue in
|
||
if let response = self.switchInterstitialAd?.responseInfo {
|
||
MP_AnalyticsManager.shared.cut_ads_showSuccessAction(response, adValue: adValue)
|
||
}
|
||
}
|
||
}else {
|
||
if let response = self.switchInterstitialAd?.responseInfo {
|
||
MP_AnalyticsManager.shared.cut_ads_showSuccessAction(response, adValue: .init())
|
||
}
|
||
}
|
||
}else if ad === loadInterstitialAd {//下载插页广告
|
||
print("当前展示的广告是下载插页广告,广告ID--\(loadInterstitialAd?.adUnitID ?? "")")
|
||
if MP_AnalyticsManager.shared.infoFromAdMobSource(switchInterstitialAd?.responseInfo) {
|
||
loadInterstitialAd?.paidEventHandler = { adValue in
|
||
if let response = self.loadInterstitialAd?.responseInfo {
|
||
MP_AnalyticsManager.shared.dl_ads_showSuccessAction(response, adValue: adValue)
|
||
}
|
||
}
|
||
}else {
|
||
if let response = self.loadInterstitialAd?.responseInfo {
|
||
MP_AnalyticsManager.shared.dl_ads_showSuccessAction(response, adValue: .init())
|
||
}
|
||
}
|
||
}else if ad === libraryInterstitialAd {//曲库插页广告
|
||
print("当前展示的广告是曲库插页广告,广告ID--\(libraryInterstitialAd?.adUnitID ?? "")")
|
||
if MP_AnalyticsManager.shared.infoFromAdMobSource(switchInterstitialAd?.responseInfo) {
|
||
libraryInterstitialAd?.paidEventHandler = { adValue in
|
||
if let response = self.libraryInterstitialAd?.responseInfo {
|
||
MP_AnalyticsManager.shared.listclk_ads_showSuccessAction(response, adValue: adValue)
|
||
}
|
||
}
|
||
}else {
|
||
if let response = self.libraryInterstitialAd?.responseInfo {
|
||
MP_AnalyticsManager.shared.listclk_ads_showSuccessAction(response, adValue: .init())
|
||
}
|
||
}
|
||
}else if ad === globalInterstitialAd {//全局插页广告
|
||
print("当前展示的广告是全局插页广告,广告ID--\(globalInterstitialAd?.adUnitID ?? "")")
|
||
}
|
||
}
|
||
//覆盖型广告已经消失
|
||
func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
|
||
//更新插页广告展示时间
|
||
interstitialDate = Date()
|
||
if ad === appOpenAd || ad === appInterstitialAd {//开屏广告
|
||
print("当前消失的广告是开屏广告,广告ID--\(appOpenAd != nil ? (appOpenAd?.adUnitID ?? ""):(appInterstitialAd?.adUnitID ?? ""))")
|
||
//执行开屏广告完成事件包
|
||
if completeOpenAdBlock != nil {
|
||
completeOpenAdBlock!()
|
||
}
|
||
}else if ad === searchInterstitialAd {//搜索插页广告
|
||
print("当前消失的广告是搜索插页广告,广告ID--\(searchInterstitialAd?.adUnitID ?? "")")
|
||
//执行搜索插页广告完成事件包
|
||
if completeSearchInterstitialAdBlock != nil {
|
||
completeSearchInterstitialAdBlock!()
|
||
}
|
||
}else if ad === playInterstitialAd {//播放插页广告
|
||
print("当前消失的广告是播放插页广告,广告ID--\(playInterstitialAd?.adUnitID ?? "")")
|
||
//执行播放插页广告完成事件包
|
||
if completePlayInterstitialAdBlock != nil {
|
||
completePlayInterstitialAdBlock!()
|
||
}
|
||
}else if ad === switchInterstitialAd {//播放插页广告
|
||
print("当前消失的广告是切歌插页广告,广告ID--\(switchInterstitialAd?.adUnitID ?? "")")
|
||
//执行播放插页广告完成事件包
|
||
if completeSwitchInterstitialAdBlock != nil {
|
||
completeSwitchInterstitialAdBlock!()
|
||
}
|
||
}else if ad === loadInterstitialAd {//下载插页广告
|
||
print("当前消失的广告是下载插页广告,广告ID--\(loadInterstitialAd?.adUnitID ?? "")")
|
||
//执行播放插页广告完成事件包
|
||
if completeLoadInterstitialAdBlock != nil {
|
||
completeLoadInterstitialAdBlock!()
|
||
}
|
||
}else if ad === libraryInterstitialAd {//曲库插页广告
|
||
print("当前消失的广告是曲库插页广告,广告ID--\(libraryInterstitialAd?.adUnitID ?? "")")
|
||
//执行搜索插页广告完成事件包
|
||
if completeLibraryInterstitialAdBlock != nil {
|
||
completeLibraryInterstitialAdBlock!()
|
||
}
|
||
}else if ad === globalInterstitialAd {///全局插页广告
|
||
print("当前消失的广告是全局插页广告,广告ID--\(globalInterstitialAd?.adUnitID ?? "")")
|
||
//执行搜索插页广告完成事件包
|
||
if completeGlobalInterstitialAdBlock != nil {
|
||
completeGlobalInterstitialAdBlock!()
|
||
}
|
||
}
|
||
|
||
}
|
||
//覆盖型广告加载出错
|
||
func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {
|
||
//更新插页广告展示时间
|
||
interstitialDate = Date()
|
||
if ad === appOpenAd || ad === appInterstitialAd {//应用开屏广告
|
||
print("开屏广告展示时出错,广告ID--\(appOpenAd != nil ? (appOpenAd?.adUnitID ?? ""):(appInterstitialAd?.adUnitID ?? "")),具体错误原因:\(error.localizedDescription)")
|
||
//判断是冷启动还是热启动
|
||
if OpenICEID.contains(where: {($0.identifier == (appOpenAd?.adUnitID ?? "") || $0.identifier == (appInterstitialAd?.adUnitID ?? ""))}) {
|
||
MP_AnalyticsManager.shared.cold_ads_showFailureAction(error.localizedDescription)
|
||
}else if OpenHOSTID.contains(where: {($0.identifier == (appOpenAd?.adUnitID ?? "") || $0.identifier == (appInterstitialAd?.adUnitID ?? ""))}) {
|
||
MP_AnalyticsManager.shared.hot_ads_showFailureAction(error.localizedDescription)
|
||
}
|
||
if completeOpenAdBlock != nil {
|
||
completeOpenAdBlock!()
|
||
}
|
||
}else if ad === searchInterstitialAd {//搜索插页广告
|
||
print("搜索插页广告展示时出错,广告ID--\(searchInterstitialAd?.adUnitID ?? ""),具体错误原因:\(error.localizedDescription)")
|
||
MP_AnalyticsManager.shared.search_ads_showFailureAction(error.localizedDescription)
|
||
if completeSearchInterstitialAdBlock != nil {
|
||
completeSearchInterstitialAdBlock!()
|
||
}
|
||
}else if ad === playInterstitialAd {//播放插页广告
|
||
print("播放插页广告展示时出错,广告ID--\(playInterstitialAd?.adUnitID ?? ""),具体错误原因:\(error.localizedDescription)")
|
||
MP_AnalyticsManager.shared.play_ads_showFailureAction(error.localizedDescription)
|
||
//执行播放插页广告完成事件包
|
||
if completePlayInterstitialAdBlock != nil {
|
||
completePlayInterstitialAdBlock!()
|
||
}
|
||
}else if ad === switchInterstitialAd {//切歌插页广告
|
||
print("切歌插页广告展示时出错,广告ID--\(switchInterstitialAd?.adUnitID ?? ""),具体错误原因:\(error.localizedDescription)")
|
||
MP_AnalyticsManager.shared.cut_ads_showFailureAction(error.localizedDescription)
|
||
//执行播放插页广告完成事件包
|
||
if completeSwitchInterstitialAdBlock != nil {
|
||
completeSwitchInterstitialAdBlock!()
|
||
}
|
||
}else if ad === loadInterstitialAd {//下载插页广告
|
||
print("下载插页广告展示时出错,广告ID--\(loadInterstitialAd?.adUnitID ?? ""),具体错误原因:\(error.localizedDescription)")
|
||
MP_AnalyticsManager.shared.dl_ads_showFailureAction(error.localizedDescription)
|
||
//执行下载插页广告完成事件包
|
||
if completeLoadInterstitialAdBlock != nil {
|
||
completeLoadInterstitialAdBlock!()
|
||
}
|
||
}else if ad === libraryInterstitialAd {//搜索插页广告
|
||
print("曲库插页广告展示时出错,广告ID--\(libraryInterstitialAd?.adUnitID ?? ""),具体错误原因:\(error.localizedDescription)")
|
||
MP_AnalyticsManager.shared.listclk_ads_showFailureAction(error.localizedDescription)
|
||
if completeLibraryInterstitialAdBlock != nil {
|
||
completeLibraryInterstitialAdBlock!()
|
||
}
|
||
}else if ad === globalInterstitialAd {//全局插页广告
|
||
print("全局插页广告展示时出错,广告ID--\(globalInterstitialAd?.adUnitID ?? ""),具体错误原因:\(error.localizedDescription)")
|
||
if completeGlobalInterstitialAdBlock != nil {
|
||
completeGlobalInterstitialAdBlock!()
|
||
}
|
||
}
|
||
|
||
}
|
||
//MARK: - GADNativeAdLoaderDelegate
|
||
// 原生广告已加载,可以展示。
|
||
func adLoader(_ adLoader: GADAdLoader, didReceive nativeAd: GADNativeAd) {
|
||
if nativeAd.mediaContent.hasVideoContent {
|
||
// //判断这个原生广告是什么类型
|
||
// nativeAd.mediaContent.videoController.setMute(true)
|
||
// nativeAd.mediaContent.videoController.delegate = self
|
||
}
|
||
if adLoader == searchAdLoader {//加载的是搜索原生广告
|
||
print("搜索原生已经加载完毕")
|
||
self.searchNativeAd = nativeAd
|
||
self.expirationSearchDate = Date()
|
||
if let block = self.onSearchNativeAdBlock {
|
||
block()
|
||
}
|
||
}else if adLoader == libraryAdLoader {//加载的是曲库原生广告
|
||
print("曲库原生已经加载完毕")
|
||
guard libraryNativeAds != nil else {
|
||
return
|
||
}
|
||
if (libraryNativeAds?.count ?? 0) < 2 {
|
||
//添加广告
|
||
libraryNativeAds?.append(nativeAd)
|
||
}else {
|
||
//已经有一批广告了,销毁掉
|
||
libraryNativeAds = []
|
||
libraryNativeAds?.append(nativeAd)
|
||
}
|
||
//判断是否加载结束
|
||
if (libraryNativeAds?.count ?? 0) == 2 {
|
||
self.expirationLibraryDate = Date()
|
||
if let block = self.onLibraryNativeAdBlock {
|
||
block()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 原生广告加载错误
|
||
func adLoader(_ adLoader: GADAdLoader, didFailToReceiveAdWithError error: any Error) {
|
||
if adLoader == searchAdLoader {//加载的是搜索原生广告
|
||
print("加载搜索原生广告发生错误,错误详情:\(error.localizedDescription)")
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 300) {
|
||
[weak self] in
|
||
guard let self = self else {return}
|
||
loadSearchNativeAd()
|
||
}
|
||
}else if adLoader == libraryAdLoader {//加载的是曲库原生广告
|
||
print("加载曲库原生广告发生错误,错误详情:\(error.localizedDescription)")
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 300) {
|
||
[weak self] in
|
||
guard let self = self else {return}
|
||
loadLibraryNativeAd()
|
||
}
|
||
}
|
||
}
|
||
// 原生广告已展示。
|
||
func nativeAdDidRecordImpression(_ nativeAd: GADNativeAd) {
|
||
print("原生广告刷新")
|
||
}
|
||
// 原生广告被点击了。
|
||
func nativeAdDidRecordClick(_ nativeAd: GADNativeAd) {
|
||
print("原生广告被点击")
|
||
}
|
||
// 原生广告将呈现全屏视图。
|
||
func nativeAdWillPresentScreen(_ nativeAd: GADNativeAd) {
|
||
print("原生广告将弹出一个新视图")
|
||
}
|
||
// 原生广告将会关闭全屏视图。
|
||
func nativeAdWillDismissScreen(_ nativeAd: GADNativeAd) {
|
||
print("原生广告视图将要关闭")
|
||
}
|
||
// 原生广告关闭了全屏视图。
|
||
func nativeAdDidDismissScreen(_ nativeAd: GADNativeAd) {
|
||
print("原生广告视图已经关闭")
|
||
}
|
||
// 原生广告将导致应用处于非活动状态并且打开新的应用。
|
||
func nativeAdWillLeaveApplication(_ nativeAd: GADNativeAd) {
|
||
|
||
}
|
||
//MARK: - GADVideoControllerDelegate
|
||
// 开始播放原生视频广告
|
||
func videoControllerDidPlayVideo(_ videoController: GADVideoController) {
|
||
//强制切回控制中心权限
|
||
|
||
}
|
||
// 暂停原生视频广告
|
||
func videoControllerDidPauseVideo(_ videoController: GADVideoController) {
|
||
//强制切回控制中心权限
|
||
|
||
}
|
||
// 停止播放视频广告
|
||
func videoControllerDidEndVideoPlayback(_ videoController: GADVideoController) {
|
||
//强制切回控制中心权限
|
||
|
||
}
|
||
}
|