157 lines
4.8 KiB
Swift
157 lines
4.8 KiB
Swift
//
|
|
// SPAppOpenAdManager.swift
|
|
// ThimraTV
|
|
//
|
|
// Created by 长沙佳儿 on 2025/7/10.
|
|
//
|
|
|
|
import UIKit
|
|
import GoogleMobileAds
|
|
|
|
@objc protocol SPAppOpenAdManagerDelegate: NSObjectProtocol {
|
|
///广告加载失败
|
|
@objc optional func appOpenAdManager(manager: SPAppOpenAdManager, didLoadFail error: Error)
|
|
///广告加载成功
|
|
@objc optional func appOpenAdManagerDidLoadFinish(manager: SPAppOpenAdManager)
|
|
///广告展示失败
|
|
@objc optional func appOpenAdManager(manager: SPAppOpenAdManager, didDisplayFail error: Error)
|
|
///广告被展示
|
|
@objc optional func appOpenAdManagerDidShow(manager: SPAppOpenAdManager)
|
|
///广告被关闭
|
|
@objc optional func appOpenAdManagerDidDismiss(manager: SPAppOpenAdManager)
|
|
}
|
|
|
|
class SPAppOpenAdManager: NSObject {
|
|
|
|
weak var delegate: SPAppOpenAdManagerDelegate?
|
|
|
|
let adUnitID = SPAdManager.manager.appOpenAdUnitID
|
|
|
|
|
|
private var appOpenAd: AppOpenAd?
|
|
private(set) var isLoadingAd = false
|
|
private(set) var isShowingAd = false
|
|
private var isNeedShow = false
|
|
|
|
static let manager = SPAppOpenAdManager()
|
|
|
|
deinit {
|
|
NotificationCenter.default.removeObserver(self)
|
|
}
|
|
|
|
override init() {
|
|
super.init()
|
|
NotificationCenter.default.addObserver(self, selector: #selector(didEnterBackgroundNotification), name: UIApplication.didEnterBackgroundNotification, object: nil)
|
|
}
|
|
|
|
private func loadAd() {
|
|
// Do not load ad if there is an unused ad or one is already loading.
|
|
if isLoadingAd || isAdAvailable() {
|
|
return
|
|
}
|
|
isLoadingAd = true
|
|
|
|
AppOpenAd.load(with: adUnitID, request: Request()) { [weak self] appOpenAd, error in
|
|
guard let self = self else { return }
|
|
self.isLoadingAd = false
|
|
|
|
self.appOpenAd = appOpenAd
|
|
self.appOpenAd?.fullScreenContentDelegate = self
|
|
|
|
if appOpenAd != nil, self.isNeedShow {
|
|
self.showAdIfAvailable()
|
|
}
|
|
if let error = error {
|
|
self.requestStatAd(type: "load_failed", errorMsg: error.localizedDescription)
|
|
self.delegate?.appOpenAdManager?(manager: self, didLoadFail: error)
|
|
} else {
|
|
self.delegate?.appOpenAdManagerDidLoadFinish?(manager: self)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
func showAdIfAvailable() {
|
|
// If the app open ad is already showing, do not show the ad again.
|
|
guard !isShowingAd else { return }
|
|
|
|
self.isNeedShow = true
|
|
|
|
// If the app open ad is not available yet but is supposed to show, load
|
|
// a new ad.
|
|
if !isAdAvailable() {
|
|
self.loadAd()
|
|
return
|
|
}
|
|
|
|
if let ad = appOpenAd {
|
|
self.isNeedShow = false
|
|
isShowingAd = true
|
|
ad.present(from: nil)
|
|
}
|
|
}
|
|
|
|
private func isAdAvailable() -> Bool {
|
|
// Check if ad exists and can be shown.
|
|
return appOpenAd != nil
|
|
}
|
|
}
|
|
|
|
extension SPAppOpenAdManager: FullScreenContentDelegate {
|
|
func adWillPresentFullScreenContent(_ ad: FullScreenPresentingAd) {
|
|
self.requestStatAd(type: "start", errorMsg: nil)
|
|
print("App open ad will be presented.")
|
|
self.delegate?.appOpenAdManagerDidShow?(manager: self)
|
|
}
|
|
|
|
func adDidDismissFullScreenContent(_ ad: FullScreenPresentingAd) {
|
|
self.requestStatAd(type: "close", errorMsg: nil)
|
|
|
|
appOpenAd = nil
|
|
isShowingAd = false
|
|
// Reload an ad.
|
|
// self.loadAd()
|
|
self.delegate?.appOpenAdManagerDidDismiss?(manager: self)
|
|
}
|
|
|
|
func ad(_ ad: FullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {
|
|
self.requestStatAd(type: "show_failed", errorMsg: error.localizedDescription)
|
|
|
|
appOpenAd = nil
|
|
isShowingAd = false
|
|
// Reload an ad.
|
|
// self.loadAd()
|
|
|
|
self.delegate?.appOpenAdManager?(manager: self, didDisplayFail: error)
|
|
}
|
|
|
|
func adDidRecordClick(_ ad: any FullScreenPresentingAd) {
|
|
self.requestStatAd(type: "click", errorMsg: nil)
|
|
}
|
|
|
|
}
|
|
|
|
//MARK: -------------- 统计 --------------
|
|
extension SPAppOpenAdManager {
|
|
|
|
private func requestStatAd(type: String, errorMsg: String?) {
|
|
let model = SPStatAdModel()
|
|
model.type = type
|
|
model.ads_id = adUnitID
|
|
model.ad_platform_key = .google
|
|
model.error_msg = errorMsg
|
|
model.scene = .splash
|
|
|
|
SPStatAPI.requestStatAd(model: model)
|
|
}
|
|
|
|
|
|
@objc private func didEnterBackgroundNotification() {
|
|
guard appOpenAd != nil else { return }
|
|
|
|
self.requestStatAd(type: "Interrupt", errorMsg: nil)
|
|
}
|
|
}
|