1430 lines
60 KiB
Swift
1430 lines
60 KiB
Swift
//
|
||
// MP_AdMobManager.swift
|
||
// relax.offline.mp3.music
|
||
//
|
||
// Created by Mr.Zhou on 2024/6/14.
|
||
//
|
||
|
||
import UIKit
|
||
import AVFoundation
|
||
import GoogleMobileAds
|
||
|
||
///广告管理器
|
||
class MP_AdMobManager: NSObject, GADFullScreenContentDelegate, GADNativeAdLoaderDelegate, GADNativeAdDelegate {
|
||
static let shared = MP_AdMobManager()
|
||
private let sharedInstance = GADMobileAds.sharedInstance()
|
||
///广告总开关
|
||
private var openAdStatus:Bool = true
|
||
///广告过期时间(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
|
||
MP_PlayerManager.shared.isAdLate = self?.interstitialSwitch
|
||
MPSideA_MediaCenterManager.shared.isAdLate = self?.interstitialSwitch
|
||
}
|
||
}
|
||
}
|
||
///插页广告显示时间
|
||
var interstitialDate:Date?
|
||
///插页广告间隔秒数(默认40秒)
|
||
private var interstitialDuration:TimeInterval = 40
|
||
///设置插页总开关
|
||
func setInterstitialSwitch(_ status:Bool) {
|
||
interstitialSwitch = status
|
||
}
|
||
///获得插页开关的状态
|
||
func getInterstitialSwitch() -> Bool {
|
||
return interstitialSwitch
|
||
}
|
||
///设置插页广告间隔秒数
|
||
func setInterstitialDuration(_ duration:TimeInterval?) {
|
||
self.interstitialDuration = duration ?? 30
|
||
}
|
||
///是否达到插页间隔时长(达到即可继续展示插页广告)
|
||
private func isShowInterstitialADAvailable(_ date:Date) -> Bool {
|
||
return Date().timeIntervalSince(date) > interstitialDuration
|
||
}
|
||
private override init() {
|
||
super.init()
|
||
reloadAdMobIDs()
|
||
//对开屏广告完成处理闭包
|
||
completeOpenAdBlock = {
|
||
[weak self] in
|
||
guard let self = self, interstitialSwitch == true else {return}
|
||
//销毁现在的开屏广告实例
|
||
appOpenAd = nil
|
||
isShowingOpenAd = false
|
||
loadOpenAdTime = nil
|
||
//关闭插页广告开关
|
||
interstitialSwitch = false
|
||
//重新加载后续的开屏广告
|
||
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
|
||
//重新加载后续的搜索插页广告
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 20) {
|
||
[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
|
||
//重新加载后续的播放插页广告
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 20) {
|
||
[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
|
||
//重新加载后续的切歌插页广告
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 20) {
|
||
[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
|
||
//重新加载后续的下载插页广告
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 20) {
|
||
[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
|
||
//重新加载后续的曲库插页广告
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 20) {
|
||
[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
|
||
//重新加载后续的全局插页广告
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 20) {
|
||
[weak self] in
|
||
self?.loadGlobalInterstitialAd { status in
|
||
if status {
|
||
print("成功加载全局插页广告")
|
||
}else {
|
||
print("全局插页广告加载失败")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///更新ID
|
||
func reloadAdMobIDs() {
|
||
//更新所有广告ID
|
||
if let str = UserDefaults.standard.string(forKey: "OpenICEID") {
|
||
print("成功提取ID")
|
||
OpenICEID = str
|
||
}
|
||
if let str = UserDefaults.standard.string(forKey: "OpenHOSTID") {
|
||
OpenHOSTID = str
|
||
}
|
||
if let str = UserDefaults.standard.string(forKey: "SearchINSERTID") {
|
||
SearchINSERTID = str
|
||
}
|
||
if let str = UserDefaults.standard.string(forKey: "SearchNATIVEID") {
|
||
SearchNATIVEID = str
|
||
}
|
||
if let str = UserDefaults.standard.string(forKey: "PlayerINSERTID") {
|
||
PlayerINSERTID = str
|
||
}
|
||
if let str = UserDefaults.standard.string(forKey: "SwitchINSERTID") {
|
||
SwitchINSERTID = str
|
||
}
|
||
if let str = UserDefaults.standard.string(forKey: "LoadINSERTID") {
|
||
LoadINSERTID = str
|
||
}
|
||
if let str = UserDefaults.standard.string(forKey: "LibraryINSERTID") {
|
||
LibraryINSERTID = str
|
||
}
|
||
if let str = UserDefaults.standard.string(forKey: "LibraryNATIVEID") {
|
||
LibraryNATIVEID = str
|
||
}
|
||
if let str = UserDefaults.standard.string(forKey: "GlobalINSERTID") {
|
||
GlobalINSERTID = str
|
||
}
|
||
}
|
||
///加载更多广告
|
||
func loadMoreAdMobs() {
|
||
guard openAdStatus else {return}
|
||
//拉取更多广告
|
||
loadSearchInterstitialAd { status in
|
||
if status {
|
||
print("成功加载搜索插页广告")
|
||
}else {
|
||
print("搜索插页广告加载失败")
|
||
}
|
||
}
|
||
loadPlayInterstitialAd{status in
|
||
if status {
|
||
print("成功加载播放插页广告")
|
||
}else {
|
||
print("播放插页广告加载失败")
|
||
}
|
||
}
|
||
}
|
||
func loadAnyAdMobs() {
|
||
guard openAdStatus else {return}
|
||
//异步加载
|
||
DispatchQueue.global(qos: .background).async {
|
||
[weak self] in
|
||
self?.loadGlobalInterstitialAd { status in
|
||
if status {
|
||
print("成功加载全局插页广告")
|
||
}else {
|
||
print("全局插页广告加载失败")
|
||
}
|
||
}
|
||
self?.loadSwitchInterstitialAd { status in
|
||
if status {
|
||
print("成功加载切歌插页广告")
|
||
}else {
|
||
print("切歌插页广告加载失败")
|
||
}
|
||
}
|
||
self?.loadLoadInterstitialAd { status in
|
||
if status {
|
||
print("成功加载下载插页广告")
|
||
}else {
|
||
print("下载插页广告加载失败")
|
||
}
|
||
}
|
||
self?.loadLibraryInterstitialAd { status in
|
||
if status {
|
||
print("成功加载曲库插页广告")
|
||
}else {
|
||
print("曲库插页广告加载失败")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
deinit{
|
||
displaySearchTimer?.invalidate()
|
||
displaySearchTimer = nil
|
||
displayLibraryTimer?.invalidate()
|
||
displayLibraryTimer = nil
|
||
}
|
||
///开始缓存广告
|
||
func start() {
|
||
sharedInstance.start { status in
|
||
print("App启动,开始加载广告")
|
||
}
|
||
}
|
||
|
||
|
||
//MARK: - 开屏
|
||
//开屏冷启动广告ID
|
||
private var OpenICEID:String!
|
||
//开屏热启动广告ID
|
||
private var OpenHOSTID:String!
|
||
//开屏广告类型
|
||
enum OpenType:Int {
|
||
//冷启动
|
||
case ICE = 0
|
||
//热启动
|
||
case HOST = 1
|
||
var title:String{
|
||
switch self {
|
||
case .ICE:
|
||
return "是冷启动开屏广告"
|
||
case .HOST:
|
||
return "是热启动开屏广告"
|
||
}
|
||
}
|
||
}
|
||
//开屏广告实例
|
||
private var appOpenAd:GADAppOpenAd?
|
||
//是否正在加载广告
|
||
private var isLoadingOpenAd:Bool = false
|
||
//是否正在展示广告
|
||
var isShowingOpenAd:Bool = false
|
||
//开屏广告加载时间
|
||
private var loadOpenAdTime:Date?
|
||
//开屏广告时间间隔(默认5秒)
|
||
private var openAppDuration:TimeInterval = 10
|
||
//设置开屏广告时间间隔
|
||
func setOpenAppDuration(_ duration:TimeInterval) {
|
||
self.openAppDuration = duration
|
||
}
|
||
//获取开屏广告时间间隔
|
||
func getOpenAppDuration() -> TimeInterval {
|
||
return self.openAppDuration
|
||
}
|
||
//开屏广告加载完成处理闭包
|
||
var completeOpenAdBlock:(() -> Void)?
|
||
|
||
///异步加载开屏广告
|
||
func loadOpenAd(_ type:OpenType,completion: @escaping (Bool) -> Void) {
|
||
guard openAdStatus else {return}
|
||
// 检测当前是否有广告或者有广告正在加载
|
||
if isLoadingOpenAd || isOpenAdAvailable() {
|
||
// 有广告或有广告在加载
|
||
completion(false)
|
||
return
|
||
}
|
||
isLoadingOpenAd = true
|
||
var UUID:String
|
||
switch type {
|
||
case .ICE:
|
||
UUID = OpenICEID
|
||
case .HOST:
|
||
UUID = OpenHOSTID
|
||
}
|
||
// 使用 GADAppOpenAd 的 load 方法和一个completion handler来加载广告
|
||
GADAppOpenAd.load(withAdUnitID: UUID, request: GADRequest()) { ad, error in
|
||
DispatchQueue.main.async { [weak self] in
|
||
guard let self = self else { return }
|
||
if let error = error {
|
||
print("加载开屏广告失败,失败原因: \(error.localizedDescription)")
|
||
self.isLoadingOpenAd = false
|
||
completion(false)
|
||
} else {
|
||
self.appOpenAd = ad
|
||
self.isLoadingOpenAd = false
|
||
//实现代理
|
||
self.appOpenAd?.fullScreenContentDelegate = self
|
||
//更新加载时间
|
||
self.loadOpenAdTime = Date()
|
||
completion(true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///开屏广告展示
|
||
func showOpenAdIfAvailable(_ type:OpenType, completion:((GADAppOpenAd) -> Void)?) {
|
||
guard openAdStatus else {return}
|
||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||
guard !interstitialSwitch, !isShowingOpenAd else { return }
|
||
// 如果应用开屏广告尚不可用但应该显示,则加载新广告。
|
||
if !isOpenAdAvailable() {
|
||
loadOpenAd(type) { [weak self] success in
|
||
guard let self = self else { return }
|
||
if success {
|
||
self.showOpenAdIfAvailable(type, completion: completion)
|
||
}
|
||
}
|
||
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)
|
||
}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!()
|
||
}
|
||
accessAppdelegate.setAudioSupport()
|
||
}
|
||
}
|
||
}
|
||
}else {
|
||
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 && wasAdexpirationTime(loadOpenAdTime)
|
||
}
|
||
|
||
//MARK: - 搜索
|
||
//搜索插页广告ID
|
||
private var SearchINSERTID:String!
|
||
//搜索原生广告ID
|
||
private var SearchNATIVEID:String!
|
||
///搜索插页广告
|
||
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 else {return}
|
||
guard let vc = searchViewController else {return}
|
||
let multipleAdOptions = GADMultipleAdsAdLoaderOptions()
|
||
//加载一条,每次即使结束后重新刷新数据
|
||
multipleAdOptions.numberOfAds = 1
|
||
searchAdLoader = GADAdLoader(adUnitID: SearchNATIVEID, rootViewController: vc, adTypes: [.native], options: [multipleAdOptions])
|
||
searchAdLoader?.delegate = self
|
||
searchAdLoader?.load(GADRequest())
|
||
}
|
||
///将加载的搜索原生广告添加到页面中
|
||
func layoutSearchNativeAd(in containerView: UIView) {
|
||
guard openAdStatus else {return}
|
||
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
|
||
MP_AnalyticsManager.shared.result_ads_chanceAction()
|
||
MP_AnalyticsManager.shared.result_ads_showAction()
|
||
// 设置展示计时器,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(completion: @escaping (Bool) -> Void) {
|
||
guard openAdStatus else {return}
|
||
// 检测当前是否有广告或者有广告正在加载
|
||
if isLoadingSearchInterstitialAd || isSearchInterstitialAdAvailable() {
|
||
// 有广告或有广告在加载
|
||
completion(false)
|
||
return
|
||
}
|
||
isLoadingSearchInterstitialAd = true
|
||
//加载搜索插页广告
|
||
GADInterstitialAd.load(withAdUnitID: SearchINSERTID, request: GADRequest()) { ad, error in
|
||
DispatchQueue.main.async { [weak self] in
|
||
guard let self = self else { return }
|
||
if let error = error {
|
||
print("加载搜索插页广告失败,失败原因: \(error.localizedDescription)")
|
||
self.isLoadingSearchInterstitialAd = false
|
||
//开始加载全局插页
|
||
loadGlobalInterstitialAd { status in
|
||
completion(status)
|
||
}
|
||
} else {
|
||
self.searchInterstitialAd = ad
|
||
self.isLoadingSearchInterstitialAd = false
|
||
//实现代理
|
||
self.searchInterstitialAd?.fullScreenContentDelegate = self
|
||
//更新加载时间
|
||
self.loadSearchInterstitialAdTime = Date()
|
||
completion(true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///搜索插页广告展示
|
||
func showSearchInterstitialAdIfAvailable(completion:((GADInterstitialAd) -> Void)?) {
|
||
guard openAdStatus else {return}
|
||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||
guard !interstitialSwitch, !isShowingSearchInterstitialAd 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)
|
||
}
|
||
}
|
||
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 if let ad = globalInterstitialAd {
|
||
//加载全局插页广告
|
||
//传递加载完成事件
|
||
if let block = completion {
|
||
block(ad)
|
||
}else {
|
||
isShowingGlobalInterstitialAd = 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:String!
|
||
///播放插页广告
|
||
var playInterstitialAd:GADInterstitialAd?
|
||
///是否正在加载播放插页广告
|
||
private var isLoadingPlayInterstitialAd:Bool = false
|
||
///是否正在展示播放插页广告
|
||
var isShowingPlayInterstitialAd:Bool = false
|
||
///播放插页加载时间
|
||
private var loadPlayInterstitialAdTime:Date?
|
||
///播放广告处理闭包
|
||
var completePlayInterstitialAdBlock:(() -> Void)?
|
||
//异步加载播放插页广告
|
||
func loadPlayInterstitialAd(completion: @escaping (Bool) -> Void) {
|
||
guard openAdStatus else {return}
|
||
// 检测当前是否有广告或者有广告正在加载
|
||
if isLoadingPlayInterstitialAd || isPlayInterstitialAdAvailable() {
|
||
// 有广告或有广告在加载
|
||
completion(false)
|
||
return
|
||
}
|
||
isLoadingPlayInterstitialAd = true
|
||
//加载播放插页广告
|
||
GADInterstitialAd.load(withAdUnitID: PlayerINSERTID, request: GADRequest()) { ad, error in
|
||
DispatchQueue.main.async { [weak self] in
|
||
guard let self = self else { return }
|
||
if let error = error {
|
||
print("加载播放插页广告失败,失败原因: \(error.localizedDescription)")
|
||
self.isLoadingPlayInterstitialAd = false
|
||
loadGlobalInterstitialAd { status in
|
||
completion(status)
|
||
}
|
||
} else {
|
||
self.playInterstitialAd = ad
|
||
self.isLoadingPlayInterstitialAd = false
|
||
//实现代理
|
||
self.playInterstitialAd?.fullScreenContentDelegate = self
|
||
//更新加载时间
|
||
self.loadPlayInterstitialAdTime = Date()
|
||
completion(true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///播放插页广告展示
|
||
func showPlayInterstitialAdIfAvailable(completion:((GADInterstitialAd) -> Void)?) {
|
||
guard openAdStatus else {return}
|
||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||
guard !interstitialSwitch, !isShowingPlayInterstitialAd else { return }
|
||
//检索是否存在插页间隔时间
|
||
if let date = interstitialDate {
|
||
if isShowInterstitialADAvailable(date) == false {
|
||
//未超过插页间隔时长
|
||
print("距上一次展示插页广告时长未超过要求,此次插页广告展示滞后")
|
||
return
|
||
}
|
||
}
|
||
// 如果播放插页广告尚不可用但应该显示,则加载新广告。
|
||
if !isPlayInterstitialAdAvailable() {
|
||
loadPlayInterstitialAd{ [weak self] success in
|
||
guard let self = self else { return }
|
||
if success {
|
||
self.showPlayInterstitialAdIfAvailable(completion: completion)
|
||
}
|
||
}
|
||
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 if let ad = globalInterstitialAd {
|
||
//加载全局插页广告
|
||
//传递加载完成事件
|
||
if let block = completion {
|
||
block(ad)
|
||
}else {
|
||
isShowingGlobalInterstitialAd = true
|
||
interstitialSwitch = true
|
||
ad.present(fromRootViewController: nil)
|
||
}
|
||
}else {
|
||
MP_AnalyticsManager.shared.play_ads_showFailureAction("Ad loading failed")
|
||
}
|
||
}
|
||
//查询是否有播放插页广告
|
||
func isPlayInterstitialAdAvailable() -> Bool {
|
||
return playInterstitialAd != nil && wasAdexpirationTime(loadPlayInterstitialAdTime)
|
||
}
|
||
|
||
|
||
//MARK: - 切歌
|
||
//切歌插页广告ID
|
||
private var SwitchINSERTID:String!
|
||
///切歌插页广告
|
||
var switchInterstitialAd:GADInterstitialAd?
|
||
///是否正在加载切歌插页广告
|
||
private var isLoadingSwitchInterstitialAd:Bool = false
|
||
///是否正在展示切歌插页广告
|
||
var isShowingSwitchInterstitialAd:Bool = false
|
||
///切歌插页加载时间
|
||
private var loadSwitchInterstitialAdTime:Date?
|
||
///切歌广告处理闭包
|
||
var completeSwitchInterstitialAdBlock:(() -> Void)?
|
||
//异步加载切歌插页广告
|
||
func loadSwitchInterstitialAd(completion: @escaping (Bool) -> Void) {
|
||
guard openAdStatus else {return}
|
||
// 检测当前是否有广告或者有广告正在加载
|
||
if isLoadingSwitchInterstitialAd || isSwitchInterstitialAdAvailable() {
|
||
// 有广告或有广告在加载
|
||
completion(false)
|
||
return
|
||
}
|
||
isLoadingSwitchInterstitialAd = true
|
||
//加载播放插页广告
|
||
GADInterstitialAd.load(withAdUnitID: SwitchINSERTID, request: GADRequest()) { ad, error in
|
||
DispatchQueue.main.async { [weak self] in
|
||
guard let self = self else { return }
|
||
if let error = error {
|
||
print("加载切歌插页广告失败,失败原因: \(error.localizedDescription)")
|
||
self.isLoadingSwitchInterstitialAd = false
|
||
loadGlobalInterstitialAd { status in
|
||
completion(status)
|
||
}
|
||
} else {
|
||
self.switchInterstitialAd = ad
|
||
self.isLoadingSwitchInterstitialAd = false
|
||
//实现代理
|
||
self.switchInterstitialAd?.fullScreenContentDelegate = self
|
||
//更新加载时间
|
||
self.loadSwitchInterstitialAdTime = Date()
|
||
completion(true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///切歌插页广告展示
|
||
func showSwitchInterstitialAdIfAvailable(completion:((GADInterstitialAd) -> Void)?) {
|
||
guard openAdStatus else {return}
|
||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||
guard !interstitialSwitch, !isShowingSwitchInterstitialAd 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)
|
||
}
|
||
}
|
||
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 if let ad = globalInterstitialAd {
|
||
//加载全局插页广告
|
||
//传递加载完成事件
|
||
if let block = completion {
|
||
block(ad)
|
||
}else {
|
||
isShowingGlobalInterstitialAd = 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:String!
|
||
///下载插页广告
|
||
var loadInterstitialAd:GADInterstitialAd?
|
||
///是否正在加载下载插页广告
|
||
private var isLoadingLoadInterstitialAd:Bool = false
|
||
///是否正在展示下载插页广告
|
||
var isShowingLoadInterstitialAd:Bool = false
|
||
///下载插页加载时间
|
||
private var loadLoadInterstitialAdTime:Date?
|
||
///下载广告处理闭包
|
||
var completeLoadInterstitialAdBlock:(() -> Void)?
|
||
//异步加载下载插页广告
|
||
func loadLoadInterstitialAd(completion: @escaping (Bool) -> Void) {
|
||
guard openAdStatus else {return}
|
||
// 检测当前是否有广告或者有广告正在加载
|
||
if isLoadingLoadInterstitialAd || isLoadInterstitialAdAvailable() {
|
||
// 有广告或有广告在加载
|
||
completion(false)
|
||
return
|
||
}
|
||
isLoadingLoadInterstitialAd = true
|
||
//加载下载插页广告
|
||
GADInterstitialAd.load(withAdUnitID: LoadINSERTID, request: GADRequest()) { ad, error in
|
||
DispatchQueue.main.async { [weak self] in
|
||
guard let self = self else { return }
|
||
if let error = error {
|
||
print("加载下载插页广告失败,失败原因: \(error.localizedDescription)")
|
||
self.isLoadingLoadInterstitialAd = false
|
||
loadGlobalInterstitialAd { status in
|
||
completion(status)
|
||
}
|
||
} else {
|
||
self.loadInterstitialAd = ad
|
||
self.isLoadingLoadInterstitialAd = false
|
||
//实现代理
|
||
self.loadInterstitialAd?.fullScreenContentDelegate = self
|
||
//更新加载时间
|
||
self.loadLoadInterstitialAdTime = Date()
|
||
completion(true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///下载插页广告展示
|
||
func showLoadInterstitialAdIfAvailable(completion:((GADInterstitialAd) -> Void)?) {
|
||
guard openAdStatus else {return}
|
||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||
guard !interstitialSwitch, !isShowingLoadInterstitialAd 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)
|
||
}
|
||
}
|
||
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 if let ad = globalInterstitialAd {
|
||
//加载全局插页广告
|
||
//传递加载完成事件
|
||
if let block = completion {
|
||
block(ad)
|
||
}else {
|
||
isShowingGlobalInterstitialAd = 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:String!
|
||
//曲库原生ID
|
||
private var LibraryNATIVEID:String!
|
||
///曲库插页广告
|
||
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 else {return}
|
||
if libraryViewController == nil {
|
||
libraryViewController = vc
|
||
}
|
||
}
|
||
///搜索原生广告加载
|
||
func loadLibraryNativeAd() {
|
||
guard openAdStatus else {return}
|
||
guard let vc = libraryViewController, libraryNativeAds == nil else {return}
|
||
let multipleAdOptions = GADMultipleAdsAdLoaderOptions()
|
||
//加载一条,每次即使结束后重新刷新数据
|
||
multipleAdOptions.numberOfAds = 2
|
||
libraryAdLoader = GADAdLoader(adUnitID: LibraryNATIVEID, rootViewController: vc, adTypes: [.native], options: [multipleAdOptions])
|
||
libraryAdLoader?.delegate = self
|
||
libraryAdLoader?.load(GADRequest())
|
||
libraryNativeAds = []
|
||
}
|
||
///将加载的搜索原生广告添加到页面中
|
||
func layoutLibraryNativeAd(in containerView: UIView, index:Int) {
|
||
guard openAdStatus else {return}
|
||
containerView.subviews.forEach { item in
|
||
item.removeFromSuperview()
|
||
}
|
||
if index == 0 {
|
||
//曲库第一页
|
||
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
|
||
MP_AnalyticsManager.shared.lbr_ads_chanceAction()
|
||
MP_AnalyticsManager.shared.lbr_ads_showAction()
|
||
}else {
|
||
//曲库第二页
|
||
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
|
||
MP_AnalyticsManager.shared.list_ads_chanceAction()
|
||
MP_AnalyticsManager.shared.list_ads_showAction()
|
||
}
|
||
DispatchQueue.main.async {
|
||
[weak self] in
|
||
containerView.snp.updateConstraints { make in
|
||
make.height.equalTo(125)
|
||
}
|
||
}
|
||
// 设置展示计时器,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(completion: @escaping (Bool) -> Void) {
|
||
guard openAdStatus else {return}
|
||
// 检测当前是否有广告或者有广告正在加载
|
||
if isLoadingLibraryInterstitialAd || isLibraryInterstitialAdAvailable() {
|
||
// 有广告或有广告在加载
|
||
completion(false)
|
||
return
|
||
}
|
||
isLoadingLibraryInterstitialAd = true
|
||
//加载曲库插页广告
|
||
GADInterstitialAd.load(withAdUnitID: LibraryINSERTID, request: GADRequest()) { ad, error in
|
||
DispatchQueue.main.async { [weak self] in
|
||
guard let self = self else { return }
|
||
if let error = error {
|
||
print("加载曲库插页广告失败,失败原因: \(error.localizedDescription)")
|
||
self.isLoadingLibraryInterstitialAd = false
|
||
loadGlobalInterstitialAd { status in
|
||
completion(status)
|
||
}
|
||
} else {
|
||
self.libraryInterstitialAd = ad
|
||
self.isLoadingLibraryInterstitialAd = false
|
||
//实现代理
|
||
self.libraryInterstitialAd?.fullScreenContentDelegate = self
|
||
//更新加载时间
|
||
self.loadLibraryInterstitialAdTime = Date()
|
||
completion(true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///曲库插页广告展示
|
||
func showLibraryInterstitialAdIfAvailable(completion:((GADInterstitialAd) -> Void)?) {
|
||
guard openAdStatus else {return}
|
||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||
guard !interstitialSwitch, !isShowingLibraryInterstitialAd 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)
|
||
}
|
||
}
|
||
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 if let ad = globalInterstitialAd {
|
||
//加载全局插页广告
|
||
|
||
//传递加载完成事件
|
||
if let block = completion {
|
||
block(ad)
|
||
}else {
|
||
isShowingGlobalInterstitialAd = 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:String!
|
||
///全局插页广告
|
||
private var globalInterstitialAd:GADInterstitialAd?
|
||
///是否正在加载全局插页广告
|
||
private var isLoadingGlobalInterstitialAd:Bool = false
|
||
///是否正在展示全局插页广告
|
||
var isShowingGlobalInterstitialAd:Bool = false
|
||
///全局插页加载时间
|
||
private var loadGlobalInterstitialAdTime:Date?
|
||
///全局广告处理闭包
|
||
var completeGlobalInterstitialAdBlock:(() -> Void)?
|
||
//异步加载全局插页广告
|
||
func loadGlobalInterstitialAd(completion: @escaping (Bool) -> Void) {
|
||
guard openAdStatus else {return}
|
||
// 检测当前是否有广告或者有广告正在加载
|
||
if isLoadingGlobalInterstitialAd || isGlobalInterstitialAdAvailable() {
|
||
// 有广告或有广告在加载
|
||
completion(false)
|
||
return
|
||
}
|
||
isLoadingGlobalInterstitialAd = true
|
||
//加载全局插页广告
|
||
GADInterstitialAd.load(withAdUnitID: GlobalINSERTID, request: GADRequest()) { ad, error in
|
||
DispatchQueue.main.async { [weak self] in
|
||
guard let self = self else { return }
|
||
if let error = error {
|
||
print("加载全局插页广告失败,失败原因: \(error.localizedDescription)")
|
||
self.isLoadingGlobalInterstitialAd = false
|
||
completion(false)
|
||
} else {
|
||
self.globalInterstitialAd = ad
|
||
self.isLoadingGlobalInterstitialAd = false
|
||
//实现代理
|
||
self.globalInterstitialAd?.fullScreenContentDelegate = self
|
||
//更新加载时间
|
||
self.loadGlobalInterstitialAdTime = Date()
|
||
completion(true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///全局插页广告展示
|
||
func showGlobalInterstitialAdIfAvailable(completion:((GADInterstitialAd) -> Void)?) {
|
||
guard openAdStatus else {return}
|
||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||
guard !interstitialSwitch, !isShowingGlobalInterstitialAd 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)
|
||
}
|
||
}
|
||
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: - 覆盖型广告代理 GADFullScreenContentDelegate
|
||
//覆盖型广告将要将要展示
|
||
func adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) {
|
||
if ad === appOpenAd {//开屏广告
|
||
print("当前展示的广告是开屏广告,广告ID--\(appOpenAd?.adUnitID ?? "")")
|
||
//判断是冷启动还是热启动
|
||
if appOpenAd?.adUnitID == OpenICEID {
|
||
MP_AnalyticsManager.shared.cold_ads_showSuccessAction()
|
||
}else if appOpenAd?.adUnitID == OpenHOSTID {
|
||
MP_AnalyticsManager.shared.hot_ads_showSuccessAction()
|
||
}
|
||
}else if ad === searchInterstitialAd {//搜索插页广告
|
||
print("当前展示的广告是搜索插页广告,广告ID--\(searchInterstitialAd?.adUnitID ?? "")")
|
||
MP_AnalyticsManager.shared.search_ads_showSuccessAction()
|
||
}else if ad === playInterstitialAd {//播放插页广告
|
||
print("当前展示的广告是播放插页广告,广告ID--\(playInterstitialAd?.adUnitID ?? "")")
|
||
MP_AnalyticsManager.shared.play_ads_showSuccessAction()
|
||
}else if ad === switchInterstitialAd {//切歌插页广告
|
||
print("当前展示的广告是切歌插页广告,广告ID--\(switchInterstitialAd?.adUnitID ?? "")")
|
||
MP_AnalyticsManager.shared.cut_ads_showSuccessAction()
|
||
}else if ad === loadInterstitialAd {//下载插页广告
|
||
print("当前展示的广告是下载插页广告,广告ID--\(loadInterstitialAd?.adUnitID ?? "")")
|
||
MP_AnalyticsManager.shared.dl_ads_showSuccessAction()
|
||
}else if ad === libraryInterstitialAd {//曲库插页广告
|
||
print("当前展示的广告是曲库插页广告,广告ID--\(libraryInterstitialAd?.adUnitID ?? "")")
|
||
MP_AnalyticsManager.shared.listclk_ads_showSuccessAction()
|
||
}else if ad === globalInterstitialAd {//全局插页广告
|
||
print("当前展示的广告是全局插页广告,广告ID--\(globalInterstitialAd?.adUnitID ?? "")")
|
||
}
|
||
}
|
||
//覆盖型广告已经消失
|
||
func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
|
||
//更新插页广告展示时间
|
||
interstitialDate = Date()
|
||
if ad === appOpenAd {//开屏广告
|
||
print("当前消失的广告是开屏广告,广告ID--\(appOpenAd?.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!()
|
||
}
|
||
}
|
||
accessAppdelegate.setAudioSupport()
|
||
}
|
||
//覆盖型广告加载出错
|
||
func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {
|
||
//更新插页广告展示时间
|
||
interstitialDate = Date()
|
||
if ad === appOpenAd {//开屏广告
|
||
print("开屏广告展示时出错,广告ID--\(appOpenAd?.adUnitID ?? ""),具体错误原因:\(error.localizedDescription)")
|
||
//判断是冷启动还是热启动
|
||
if appOpenAd?.adUnitID == OpenICEID {
|
||
MP_AnalyticsManager.shared.cold_ads_showFailureAction(error.localizedDescription)
|
||
}else if appOpenAd?.adUnitID == OpenHOSTID {
|
||
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!()
|
||
}
|
||
}
|
||
accessAppdelegate.setAudioSupport()
|
||
}
|
||
//MARK: - GADNativeAdLoaderDelegate
|
||
// 原生广告已展示。
|
||
func nativeAdDidRecordImpression(_ nativeAd: GADNativeAd) {
|
||
|
||
}
|
||
// 原生广告被点击了。
|
||
func nativeAdDidRecordClick(_ nativeAd: GADNativeAd) {
|
||
|
||
}
|
||
// 原生广告将呈现全屏视图。
|
||
func nativeAdWillPresentScreen(_ nativeAd: GADNativeAd) {
|
||
|
||
}
|
||
// 原生广告将会关闭全屏视图。
|
||
func nativeAdWillDismissScreen(_ nativeAd: GADNativeAd) {
|
||
|
||
}
|
||
// 原生广告关闭了全屏视图。
|
||
func nativeAdDidDismissScreen(_ nativeAd: GADNativeAd) {
|
||
|
||
}
|
||
// 原生广告将导致应用处于非活动状态并且打开新的应用。
|
||
func nativeAdWillLeaveApplication(_ nativeAd: GADNativeAd) {
|
||
|
||
}
|
||
// 原生广告已加载,可以展示。
|
||
func adLoader(_ adLoader: GADAdLoader, didReceive nativeAd: GADNativeAd) {
|
||
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()
|
||
}
|
||
}
|
||
}
|
||
}
|