322 lines
9.5 KiB
Swift
322 lines
9.5 KiB
Swift
//
|
|
// SPRewardedAdManager.swift
|
|
// ThimraTV
|
|
//
|
|
// Created by 长沙佳儿 on 2025/7/10.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
@objc protocol SPRewardedAdManagerDelegate: NSObjectProtocol {
|
|
///发放奖励
|
|
@objc optional func rewardedAdManager(manager: SPRewardedAdManager, userDidEarnReward adInfo: SPAdInfo)
|
|
///广告加载失败
|
|
@objc optional func rewardedAdManager(manager: SPRewardedAdManager, didLoadFail error: Error)
|
|
///广告加载成功
|
|
@objc optional func rewardedAdManagerDidLoadFinish(manager: SPRewardedAdManager)
|
|
///广告展示失败
|
|
@objc optional func rewardedAdManager(manager: SPRewardedAdManager, didDisplayFail error: Error)
|
|
///广告被展示
|
|
@objc optional func rewardedAdManagerDidShow(manager: SPRewardedAdManager)
|
|
///广告被关闭
|
|
@objc optional func rewardedAdManager(manager: SPRewardedAdManager, didDismiss adInfo: SPAdInfo)
|
|
}
|
|
|
|
class SPRewardedAdManager: NSObject {
|
|
|
|
static let manager = SPRewardedAdManager()
|
|
|
|
weak var delegate: SPRewardedAdManagerDelegate?
|
|
|
|
private(set) var isLoadingRewardedAd = false
|
|
|
|
///重试等待时长
|
|
private var retryAttempt = 0.0
|
|
///重试次数
|
|
private var retryCount = 0
|
|
///最大重试次数
|
|
private let retryMaxCount = 1
|
|
///广告激活状态
|
|
private(set) var isEnable = true
|
|
|
|
private(set) var adInfo: SPAdInfo?
|
|
|
|
private(set) var isShowLoading = false
|
|
private(set) var isShowToast = false
|
|
|
|
private var adsDate: Date?
|
|
///统计场景
|
|
var statScene: SPStatAdModel.AdScene?
|
|
var videoInfo: SPVideoInfoModel?
|
|
|
|
|
|
deinit {
|
|
NotificationCenter.default.removeObserver(self)
|
|
}
|
|
|
|
override init() {
|
|
super.init()
|
|
NotificationCenter.default.addObserver(self, selector: #selector(didEnterBackgroundNotification), name: UIApplication.didEnterBackgroundNotification, object: nil)
|
|
}
|
|
|
|
func isAdAvailable() -> Bool {
|
|
guard let adInfo = adInfo else { return false }
|
|
if adInfo.platform_key == .google {
|
|
return admob_isReady()
|
|
} else if adInfo.platform_key == .applovin {
|
|
return appLovin_isReady()
|
|
}
|
|
return false
|
|
}
|
|
|
|
///加载并展示激励广告
|
|
func loadAndShowRewardedAd(isShowLoading: Bool = false, isShowToast: Bool = true) {
|
|
guard isEnable else {
|
|
let text = "movia_no_ads_tip".localized
|
|
if isShowToast {
|
|
self.showToast(text: text)
|
|
}
|
|
self.isShowToast = false
|
|
self.isShowLoading = false
|
|
let error = NSError(domain: text.localized, code: -1)
|
|
loadFailHandler(isStat: false, error: error)
|
|
return
|
|
}
|
|
|
|
self.isShowLoading = isShowLoading
|
|
self.isShowToast = isShowToast
|
|
|
|
if self.isShowLoading {
|
|
SPHUD.show()
|
|
}
|
|
|
|
guard !isLoadingRewardedAd else { return }
|
|
if !isAdAvailable() {
|
|
self.isLoadingRewardedAd = true
|
|
}
|
|
|
|
self.requestAdInfo { [weak self] adInfo in
|
|
guard let self = self else { return }
|
|
|
|
if adInfo.platform_key == .google {
|
|
self.admob_loadAndShowRewardedAd(adInfo: adInfo)
|
|
} else if adInfo.platform_key == .applovin {
|
|
self.appLovin_loadAndShowRewardedAd(adInfo: adInfo)
|
|
} else {
|
|
self.isLoadingRewardedAd = false
|
|
self.adInfo = nil
|
|
}
|
|
}
|
|
}
|
|
|
|
///预加载一个广告
|
|
func preloadRewardedAd() {
|
|
guard isEnable else { return }
|
|
guard !isLoadingRewardedAd else { return }
|
|
|
|
isShowLoading = false
|
|
isShowToast = false
|
|
|
|
self.isLoadingRewardedAd = true
|
|
|
|
self.requestAdInfo { [weak self] adInfo in
|
|
guard let self = self else { return }
|
|
if adInfo.platform_key == .google {
|
|
self.admob_loadRewardedAd(adInfo: adInfo)
|
|
} else if adInfo.platform_key == .applovin {
|
|
self.appLovin_loadRewardedAd(adInfo: adInfo)
|
|
} else {
|
|
self.isLoadingRewardedAd = false
|
|
self.adInfo = nil
|
|
}
|
|
}
|
|
}
|
|
|
|
///重试加载广告
|
|
private func retryLoadAd() {
|
|
guard isEnable else { return }
|
|
|
|
guard retryCount < retryMaxCount else {
|
|
retryCount = 0
|
|
retryAttempt = 0
|
|
return
|
|
}
|
|
|
|
retryCount += 1
|
|
retryAttempt += 1
|
|
let delaySec = pow(2.0, min(6.0, retryAttempt))
|
|
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + delaySec) { [weak self] in
|
|
self?.preloadRewardedAd()
|
|
}
|
|
}
|
|
|
|
private func clean() {
|
|
self.statScene = nil
|
|
self.videoInfo = nil
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//MARK: -------------- 广告内部调用(事件回调) --------------
|
|
extension SPRewardedAdManager {
|
|
|
|
///奖励发放回调
|
|
func userDidEarnRewardHandler() {
|
|
guard let adInfo = adInfo else { return }
|
|
self.delegate?.rewardedAdManager?(manager: self, userDidEarnReward: adInfo)
|
|
self.requestStatAd(type: "reward", errorMsg: nil)
|
|
}
|
|
|
|
///广告加载失败
|
|
func loadFailHandler(isStat: Bool = true, error: Error) {
|
|
|
|
if isShowLoading {
|
|
SPHUD.dismiss()
|
|
}
|
|
if isShowToast {
|
|
self.showToast()
|
|
}
|
|
self.isLoadingRewardedAd = false
|
|
self.delegate?.rewardedAdManager?(manager: self, didLoadFail: error)
|
|
if isStat {
|
|
self.requestStatAd(type: "load_failed", errorMsg: error.localizedDescription)
|
|
}
|
|
|
|
self.clean()
|
|
|
|
if self.adInfo?.platform_key != .google {//谷歌广告兜底
|
|
self.isLoadingRewardedAd = true
|
|
let adInfo = SPAdInfo()
|
|
adInfo.platform_key = .google
|
|
adInfo.ads_id = SPAdManager.manager.admob_rewardedAdUnitID
|
|
self.adInfo = adInfo
|
|
self.admob_loadRewardedAd(adInfo: adInfo)
|
|
|
|
} else {
|
|
self.isEnable = false
|
|
self.retryLoadAd()
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
///广告加载成功
|
|
func loadFinishHandler() {
|
|
self.retryAttempt = 0
|
|
self.retryCount = 0
|
|
self.isLoadingRewardedAd = false
|
|
self.delegate?.rewardedAdManagerDidLoadFinish?(manager: self)
|
|
}
|
|
|
|
///广告展示失败
|
|
func displayFailHandler(error: Error) {
|
|
if isShowLoading {
|
|
SPHUD.dismiss()
|
|
}
|
|
if isShowToast {
|
|
self.showToast()
|
|
}
|
|
self.delegate?.rewardedAdManager?(manager: self, didDisplayFail: error)
|
|
self.requestStatAd(type: "show_failed", errorMsg: error.localizedDescription)
|
|
|
|
self.clean()
|
|
}
|
|
|
|
///广告被展示
|
|
func didShowHandler() {
|
|
self.adsDate = Date()
|
|
|
|
if isShowLoading {
|
|
SPHUD.dismiss()
|
|
}
|
|
self.delegate?.rewardedAdManagerDidShow?(manager: self)
|
|
|
|
self.requestStatAd(type: "start", errorMsg: nil)
|
|
}
|
|
///广告被关闭
|
|
func didDismissHandler() {
|
|
let adInfo = self.adInfo
|
|
|
|
var seconds = 0
|
|
if let adsDate = self.adsDate {
|
|
seconds = Int(Date().timeIntervalSince(adsDate))
|
|
}
|
|
|
|
self.requestStatAd(type: "close", seconds: seconds, errorMsg: nil) { [weak self] in
|
|
guard let self = self else { return }
|
|
if let adInfo = adInfo {
|
|
self.delegate?.rewardedAdManager?(manager: self, didDismiss: adInfo)
|
|
}
|
|
|
|
}
|
|
self.clean()
|
|
self.preloadRewardedAd()
|
|
|
|
}
|
|
|
|
///广告被点击
|
|
func didClickHandler() {
|
|
var seconds = 0
|
|
if let adsDate = self.adsDate {
|
|
seconds = Int(Date().timeIntervalSince(adsDate))
|
|
}
|
|
|
|
self.requestStatAd(type: "click", seconds: seconds, errorMsg: nil)
|
|
}
|
|
|
|
}
|
|
|
|
extension SPRewardedAdManager {
|
|
|
|
private func requestStatAd(type: String, seconds: Int = 0, errorMsg: String?, completer: (() -> Void)? = nil) {
|
|
guard let adInfo = adInfo else { return }
|
|
|
|
let model = SPStatAdModel()
|
|
model.type = type
|
|
model.ads_id = adInfo.ads_id
|
|
model.view_seconds = seconds
|
|
model.ad_platform_key = adInfo.platform_key
|
|
model.error_msg = errorMsg
|
|
model.scene = self.statScene
|
|
model.short_play_id = self.videoInfo?.short_play_id
|
|
model.short_play_video_id = self.videoInfo?.short_play_video_id
|
|
|
|
SPStatAPI.requestStatAd(model: model, completer: completer)
|
|
}
|
|
|
|
|
|
@objc private func didEnterBackgroundNotification() {
|
|
if self.statScene == nil { return }
|
|
|
|
self.requestStatAd(type: "Interrupt", seconds: 0, errorMsg: nil)
|
|
}
|
|
|
|
func showToast(text: String? = "movia_no_ads_tip".localized) {
|
|
SPToast.show(text: text)
|
|
}
|
|
|
|
|
|
private func requestAdInfo(completer: ((_ adInfo: SPAdInfo) -> Void)?) {
|
|
|
|
if let adInfo = self.adInfo {
|
|
completer?(adInfo)
|
|
return
|
|
}
|
|
SPAdAPI.requestShowAdInfo { [weak self] adInfo in
|
|
guard let self = self else { return }
|
|
|
|
if let adInfo = adInfo {
|
|
self.adInfo = adInfo
|
|
} else {
|
|
self.adInfo = SPAdInfo()
|
|
self.adInfo?.platform_key = .google
|
|
self.adInfo?.ads_id = SPAdManager.manager.admob_rewardedAdUnitID
|
|
}
|
|
completer?(self.adInfo!)
|
|
}
|
|
}
|
|
}
|