开屏广告统计

This commit is contained in:
湖北秦九 2026-02-12 09:09:03 +08:00
parent cc918f56d9
commit 5d8529dd95
6 changed files with 97 additions and 24 deletions

View File

@ -143,4 +143,10 @@ extension FABannerAdManager: FABannerAdDelegate {
}
extension FABannerAdManager {
}

View File

@ -22,6 +22,7 @@ class FAAdManager: NSObject {
case reward = "reward"
case splash = "splash"
case banner = "banner"
case open = "open"
}
static func initSdk() {

View File

@ -20,6 +20,6 @@ class FAUploadAdsPriceModel: NSObject, SmartCodable {
var alliance_name: String?
var money: String?
var scene: FAAdManager.BusinessScene?
var currency: String = "USD"
}

View File

@ -23,10 +23,12 @@ import UIKit
}
protocol FAOpenAdDelegate: NSObjectProtocol {
func fa_openAd(ad: FAOpenAd, didLoadFail error: Error)
func fa_openAdDidStartLoad(ad: FAOpenAd)
func fa_openAdDidLoadFinish(ad: FAOpenAd)
func fa_openAd(ad: FAOpenAd, didLoadFail error: Error)
func fa_openAd(ad: FAOpenAd, didDisplayFail error: Error)
func fa_openAdDidShow(ad: FAOpenAd)
func fa_openAdDidShow(ad: FAOpenAd, adInfo: [AnyHashable : Any])
func fa_openAdDidDismiss(ad: FAOpenAd)
func fa_openAdDidClick(ad: FAOpenAd)
}
@ -36,6 +38,7 @@ protocol FAOpenAd: NSObjectProtocol {
var adPlatform: FAAdPlatform { get }
var adType: FAAdType { get }
var adUnitID: String { get }
var networkName: String { get set }
var isReady: Bool { get }
func loadAd()
@ -67,6 +70,10 @@ class FAOpenAdManager: NSObject {
private(set) var isWaitingToShow = false
private var timeOutTimer: Timer?
private var startShowDate: Date?
private var startLoadDate: Date?
private var endLoadDate: Date?
var isAdAvailable: Bool {
return appOpenAd?.isReady ?? false
}
@ -128,6 +135,8 @@ class FAOpenAdManager: NSObject {
showAd()
return
}
self.startLoadDate = nil
self.endLoadDate = nil
// 2.
isWaitingToShow = true
@ -168,17 +177,25 @@ class FAOpenAdManager: NSObject {
// MARK: - BRAppOpenAdDelegate
extension FAOpenAdManager: FAOpenAdDelegate {
func fa_openAdDidStartLoad(ad: any FAOpenAd) {
self.startLoadDate = Date()
self.uploadAdsHistory(ad: ad, type: "startLoad")
}
func fa_openAd(ad: FAOpenAd, didLoadFail error: Error) {
self.endLoadDate = Date()
isLoadingAd = false
isWaitingToShow = false
appOpenAd = nil
clearTimer()
requestStatAd(type: "load_failed", errorMsg: error.localizedDescription)
uploadAdsHistory(ad: ad, type: "load_failed", errorMsg: error.localizedDescription)
delegate?.fa_openAdManager?(manager: self, didLoadFail: error)
}
func fa_openAdDidLoadFinish(ad: FAOpenAd) {
self.endLoadDate = Date()
isLoadingAd = false
self.uploadAdsHistory(ad: ad, type: "endLoad")
delegate?.fa_openAdManagerDidLoadFinish?(manager: self)
//
@ -193,18 +210,26 @@ extension FAOpenAdManager: FAOpenAdDelegate {
isWaitingToShow = false
appOpenAd = nil
clearTimer()
requestStatAd(type: "show_failed", errorMsg: error.localizedDescription)
uploadAdsHistory(ad: ad, type: "show_failed", errorMsg: error.localizedDescription)
delegate?.fa_openAdManager?(manager: self, didDisplayFail: error)
}
func fa_openAdDidShow(ad: FAOpenAd) {
requestStatAd(type: "start", errorMsg: nil)
func fa_openAdDidShow(ad: any FAOpenAd, adInfo: [AnyHashable : Any]) {
self.startShowDate = Date()
self.uploadAdsHistory(ad: ad, type: "start", viewSeconds: 0)
self.requestUploadAdsPrice(ad: ad, adInfo: adInfo)
delegate?.fa_openAdManagerDidShow?(manager: self)
}
func fa_openAdDidDismiss(ad: FAOpenAd) {
isShowingAd = false
appOpenAd = nil
var viewSeconds: Int? = nil
if let startShowDate = self.startShowDate {
viewSeconds = Int(Date().timeIntervalSince(startShowDate))
}
self.uploadAdsHistory(ad: ad, type: "close", viewSeconds: viewSeconds)
delegate?.fa_openAdManagerDidDismiss?(manager: self)
// 5
DispatchQueue.main.asyncAfter(deadline: .now() + 10) { [weak self] in
@ -214,30 +239,27 @@ extension FAOpenAdManager: FAOpenAdDelegate {
}
func fa_openAdDidClick(ad: FAOpenAd) {
requestStatAd(type: "click", errorMsg: nil)
var viewSeconds: Int? = nil
if let startShowDate = self.startShowDate {
viewSeconds = Int(Date().timeIntervalSince(startShowDate))
}
self.uploadAdsHistory(ad: ad, type: "click", viewSeconds: viewSeconds)
}
}
// MARK: - Statistics
extension FAOpenAdManager {
private func requestStatAd(type: String, errorMsg: String?) {
guard let appOpenAd = appOpenAd else { return }
// let model = SPStatAdModel()
// model.type = type
// model.ads_id = appOpenAd.adUnitID
// model.ad_platform_key = SPAdPlatformKey(rawValue: appOpenAd.adPlatformKey)
// model.error_msg = errorMsg
// model.scene = .splash
//
// SPStatAPI.requestStatAd(model: model)
}
@objc private func didEnterBackgroundNotification() {
if !self.isShowingAd { return }
guard let ad = self.appOpenAd else { return }
self.requestStatAd(type: "Interrupt", errorMsg: nil)
var viewSeconds: Int? = nil
if let startShowDate = self.startShowDate {
viewSeconds = Int(Date().timeIntervalSince(startShowDate))
}
self.uploadAdsHistory(ad: ad, type: "Interrupt", viewSeconds: viewSeconds)
}
@objc private func didBecomeActiveNotification() {
@ -246,4 +268,41 @@ extension FAOpenAdManager {
self.showAd()
}
}
func uploadAdsHistory(ad: any FAOpenAd, type: String, viewSeconds: Int? = nil, errorMsg: String? = nil) {
var loadTime: Int?
if let startDate = self.startLoadDate, let endDate = self.endLoadDate {
loadTime = Int(endDate.timeIntervalSince(startDate))
}
let model = FAAdStatModel()
model.scene = .open
if let loadTime = loadTime {
model.loading_time = max(0, loadTime)
}
model.view_seconds = viewSeconds
model.ad_type = ad.adType.rawValue
model.ads_id = ad.adUnitID
model.ad_platform_key = ad.adPlatform
model.type = type
model.ag_platform_name = ad.networkName
model.ad_platform_name = ad.adPlatform
FAStatAPI.requestUploadAdsHistory(model: model)
}
func requestUploadAdsPrice(ad: any FAOpenAd, adInfo: [AnyHashable : Any]) {
guard let ecpm = adInfo["ecpm"] as? String else { return }
let money = (NSNumber(string: ecpm)?.doubleValue ?? 0) / 1000
let model = FAUploadAdsPriceModel()
model.short_play_launch_id = ad.adUnitID
model.type = ad.adType.rawValue
model.agent_name = ad.adPlatform.rawValue
model.alliance_name = ad.networkName
model.money = "\(money)"
model.scene = .open
FAStatAPI.requestUploadAdsPrice(model: model)
}
}

View File

@ -29,6 +29,8 @@ class FATradPlusOpenAd: NSObject, FAOpenAd {
var adUnitID: String {
return self.adPlatform.openUnitId
}
var networkName: String = ""
var isReady: Bool {
#if canImport(TradPlusAds)
@ -78,7 +80,12 @@ class FATradPlusOpenAd: NSObject, FAOpenAd {
// MARK: - TradPlusADSplashDelegate
extension FATradPlusOpenAd: TradPlusADSplashDelegate {
func tpSplashAdStartLoad(_ adInfo: [AnyHashable : Any]) {
self.delegate?.fa_openAdDidStartLoad(ad: self)
}
func tpSplashAdLoaded(_ adInfo: [AnyHashable : Any]) {
self.networkName = (adInfo["adNetworkName"] as? String) ?? "unknown"
self.delegate?.fa_openAdDidLoadFinish(ad: self)
}
@ -88,7 +95,7 @@ extension FATradPlusOpenAd: TradPlusADSplashDelegate {
}
func tpSplashAdImpression(_ adInfo: [AnyHashable : Any]) {
self.delegate?.fa_openAdDidShow(ad: self)
self.delegate?.fa_openAdDidShow(ad: self, adInfo: adInfo)
}
func tpSplashAdShow(_ adInfo: [AnyHashable : Any], didFailWithError error: Error) {

View File

@ -112,6 +112,8 @@ class FARewardedAdManager: NSObject {
}
if self.isAdAvailable { return }
if self.isLoadingAd { return }
self.startLoadDate = nil
self.endLoadDate = nil
self.isLoadingAd = true
@ -144,7 +146,6 @@ extension FARewardedAdManager: FARewardedAdDelegate {
self.isLoadingAd = false
self.uploadAdsHistory(ad: ad, type: "load_failed", errorMsg: error.localizedDescription)
self.delegate?.fa_rewardedAdManager?(adManager: self, didLoadFail: error)
self.endLoadDate = nil
}
func fa_rewardedAd(ad: any FARewardedAd, didDisplayFail error: any Error) {
@ -164,7 +165,6 @@ extension FARewardedAdManager: FARewardedAdDelegate {
self.endLoadDate = Date()
self.uploadAdsHistory(ad: ad, type: "endLoad")
self.delegate?.fa_rewardedAdManagerDidLoadFinish?(adManager: self)
self.endLoadDate = nil
}
func fa_rewardedAdDidShow(ad: any FARewardedAd, adInfo: [AnyHashable : Any]) {