276 lines
10 KiB
Swift
276 lines
10 KiB
Swift
//
|
||
// MP_AdMobManager.swift
|
||
// relax.offline.mp3.music
|
||
//
|
||
// Created by Mr.Zhou on 2024/6/14.
|
||
//
|
||
|
||
import UIKit
|
||
import GoogleMobileAds
|
||
///广告管理器
|
||
class MP_AdMobManager: NSObject, GADFullScreenContentDelegate {
|
||
static let shared = MP_AdMobManager()
|
||
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
|
||
//设置插页总开关
|
||
func setInterstitialSwitch(_ status:Bool) {
|
||
interstitialSwitch = status
|
||
}
|
||
|
||
private override init() {
|
||
super.init()
|
||
//对开屏广告完成处理闭包
|
||
completeOpenAdBlock = {
|
||
[weak self] in
|
||
guard let self = self, interstitialSwitch == true else {return}
|
||
//销毁现在的开屏广告实例
|
||
appOpenAd = nil
|
||
isShowingOpenAd = false
|
||
loadOpenAdTime = nil
|
||
//关闭插页广告开关
|
||
interstitialSwitch = false
|
||
//重新加载后续的开屏广告
|
||
loadOpenAd(.HOST) { status in
|
||
if status == true {
|
||
print("新的开屏广告加载成功")
|
||
}else {
|
||
print("开屏广告加载失败了")
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
///开始缓存广告
|
||
func start() {
|
||
sharedInstance.start { status in
|
||
print("App启动,开始加载广告")
|
||
}
|
||
}
|
||
|
||
|
||
//MARK: - 开屏
|
||
//开屏冷启动广告ID
|
||
private let OpenICEID:String = "ca-app-pub-3940256099942544/5575463023"
|
||
//开屏热启动广告ID
|
||
private let OpenHOSTID:String = "ca-app-pub-3940256099942544/5575463023"
|
||
//开屏广告类型
|
||
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
|
||
//是否正在展示广告
|
||
private var isShowingOpenAd:Bool = false
|
||
//开屏广告加载时间
|
||
private var loadOpenAdTime:Date?
|
||
//开屏广告加载完成处理闭包
|
||
var completeOpenAdBlock:(() -> Void)?
|
||
|
||
//异步加载开屏广告
|
||
func loadOpenAd(_ type:OpenType,completion: @escaping (Bool) -> Void) {
|
||
// 检测当前是否有广告或者有广告正在加载
|
||
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 !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 let ad = appOpenAd {
|
||
isShowingOpenAd = true
|
||
//传递加载完成事件
|
||
if let block = completion {
|
||
block(ad)
|
||
}else {
|
||
interstitialSwitch = true
|
||
ad.present(fromRootViewController: nil)
|
||
}
|
||
}
|
||
}
|
||
//查询是否有开屏广告
|
||
func isOpenAdAvailable() -> Bool {
|
||
return appOpenAd != nil && wasAdexpirationTime(loadOpenAdTime)
|
||
}
|
||
|
||
//MARK: - 搜索
|
||
//搜索插页广告ID
|
||
private let SearchINSERTID:String = "ca-app-pub-3940256099942544/4411468910"
|
||
//搜索原生广告ID
|
||
private let SearchNATIVEID:String = "ca-app-pub-1371732277241593/5674216970"
|
||
///搜索插页广告
|
||
private var searchInterstitialAd:GADInterstitialAd?
|
||
///是否正在加载搜索插页广告
|
||
private var isLoadingSearchInterstitialAd:Bool = false
|
||
///是否正在展示搜索插页广告
|
||
private var isShowingSearchInterstitialAd:Bool = false
|
||
///搜索插页加载时间
|
||
private var loadSearchInterstitialAdTime:Date?
|
||
|
||
//异步加载搜索插页广告
|
||
func loadSearchInterstitialAd(completion: @escaping (Bool) -> Void) {
|
||
// 检测当前是否有广告或者有广告正在加载
|
||
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
|
||
completion(false)
|
||
} else {
|
||
self.searchInterstitialAd = ad
|
||
self.isLoadingSearchInterstitialAd = false
|
||
//实现代理
|
||
self.searchInterstitialAd?.fullScreenContentDelegate = self
|
||
//更新加载时间
|
||
self.loadSearchInterstitialAdTime = Date()
|
||
completion(true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
///搜索插页广告展示
|
||
func showSearchInterstitialAdIfAvailable(completion:((GADInterstitialAd) -> Void)?) {
|
||
// 如果应用插页广告或者开屏广告已经正在展示,则不再展示该广告。
|
||
guard !interstitialSwitch, !isShowingSearchInterstitialAd else { return }
|
||
// 如果应用开屏广告尚不可用但应该显示,则加载新广告。
|
||
if !isSearchInterstitialAdAvailable() {
|
||
loadSearchInterstitialAd { [weak self] success in
|
||
guard let self = self else { return }
|
||
if success {
|
||
self.showSearchInterstitialAdIfAvailable(completion: completion)
|
||
}
|
||
}
|
||
return
|
||
}
|
||
//当开屏广告确定有值后展示
|
||
if let ad = searchInterstitialAd {
|
||
isShowingSearchInterstitialAd = true
|
||
//传递加载完成事件
|
||
if let block = completion {
|
||
block(ad)
|
||
}else {
|
||
interstitialSwitch = true
|
||
ad.present(fromRootViewController: nil)
|
||
}
|
||
}
|
||
}
|
||
//查询是否有搜索插页广告
|
||
func isSearchInterstitialAdAvailable() -> Bool {
|
||
return appOpenAd != nil && wasAdexpirationTime(loadSearchInterstitialAdTime)
|
||
}
|
||
|
||
//MARK: - 播放
|
||
//播放插页广告ID
|
||
private let PlayerINSERTID:String = "ca-app-pub-3940256099942544/4411468910"
|
||
//切歌插页广告ID
|
||
private let SwitchINSERTID:String = "ca-app-pub-3940256099942544/4411468910"
|
||
//下载插页广告ID
|
||
private let LoadINSERTID:String = "ca-app-pub-3940256099942544/4411468910"
|
||
//MARK: - 曲库
|
||
//曲库插页ID
|
||
private let LibraryINSERTID:String = "ca-app-pub-3940256099942544/4411468910"
|
||
//曲库原生ID
|
||
private let LibraryNATIVEID:String = "ca-app-pub-1371732277241593/4683255855"
|
||
//MARK: - 全局
|
||
//全局备用插页ID
|
||
private let GlobalINSERTID:String = "ca-app-pub-3940256099942544/4411468910"
|
||
|
||
|
||
//MARK: - 覆盖型广告代理 GADFullScreenContentDelegate
|
||
//覆盖型广告将要将要展示
|
||
func adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) {
|
||
if ad === appOpenAd {
|
||
print("当前展示的覆盖型广告是开屏广告,广告ID--\(appOpenAd!.adUnitID)")
|
||
}
|
||
}
|
||
//覆盖型广告已经消失
|
||
func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
|
||
if ad === appOpenAd {
|
||
print("当前消失的覆盖型广告是开屏广告,广告ID--\(appOpenAd!.adUnitID)")
|
||
if completeOpenAdBlock != nil {
|
||
completeOpenAdBlock!()
|
||
}
|
||
}
|
||
}
|
||
//覆盖型广告加载出错
|
||
func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {
|
||
if ad === appOpenAd {
|
||
print("覆盖型广告出错,广告ID--\(appOpenAd!.adUnitID)")
|
||
if completeOpenAdBlock != nil {
|
||
completeOpenAdBlock!()
|
||
}
|
||
}
|
||
}
|
||
}
|