build-ipa/max/template/playbtest/playbtest/PlayB/bbbAdManager.swift
2025-11-25 15:56:37 +08:00

501 lines
18 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// bbbAdManager.swift
// playbtest
//
// Created by mac on 2025/3/11.
//
import Foundation
import AppLovinSDK
class bConfig: NSObject {
/// 广Key
var adKey:String = "{adKey}"
/// 广
var allAdIds:[String] = [{allAdIds}]
/// 广
var adids:[String] = []
///ID
var adbrush_deviceid:String?
///ecpm
var adbrush_ecpm:Double = 0.001
/// ip
var adbrush_localip:String?
/// Aload show
var adbrush_base_url:String = "http://192.168.40.8:8080"
///
var adbrush_local_url:String = "http://127.0.0.1:6000"
/// ip
var remoteIp:String = ""
/// dataId
var dataId:String = ""
///IDFA
var idfa:String = ""
///
var washParam:Bool = false
///
var linkId:String = ""
var device_model: String = ""
///load
var loadcount:Int = 0
var ipTime:Int = 0
var udp_port:Int = 6001
override init() {
super.init()
if self.allAdIds.count > 3 {
self.adids = Array(self.allAdIds.shuffled().prefix(3))
} else {
self.adids = self.allAdIds
}
}
///
@objc dynamic var isadsureshow:Bool = false
func getRandomString() -> String? {
return adids.randomElement()
}
// 广
func isADSSMode() -> Bool {
// return true
return UserDefaults.standard.bool(forKey: "kLuxSSFaceKey")
}
}
class AdItem :NSObject,MAAdDelegate{
var interstitialAd:MAInterstitialAd!
var interstitialAdID: String = ""
var retryAttempt = 0.0
// 广
var onAdClosed: (() -> Void)?
var onStatusChange:((_:String,_:Int, _:Double) -> Void)?
var startLoadTime: DispatchTime?
// 0: 1:2:3:4:5:6:
private(set) var status: Int = 0
private(set) var ecpm:Double = 0.0
init(adID:String){
super.init()
self.interstitialAdID = adID
// loadInterstitialAd()
}
func changeStatus(st:Int) {
self.status = st
onStatusChange?(self.interstitialAdID, st, self.ecpm)
}
func getLoadTime() -> Int {
var time = 0
if let startTime = startLoadTime {
let loadDuration = calculateElapsedTime(since: startTime)
time = loadDuration
}
return time
}
func loadInterstitialAd(){
interstitialAd = MAInterstitialAd(adUnitIdentifier:interstitialAdID)
interstitialAd.delegate = self
startLoadTime = DispatchTime.now()
changeStatus(st: 1)
NSLog("XS loadInterstitialAd\(self.interstitialAdID)")
interstitialAd.load()
NSLog("XS loadInterstitialAd 2 \(self.interstitialAdID)");
}
func showAd(onAdClosed: @escaping () -> Void) {
self.onAdClosed = onAdClosed
NSLog("onAdClosed set: \(self.onAdClosed != nil)")
interstitialAd.show(forPlacement: interstitialAdID)
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "---走到了show\(interstitialAdID)"])
}
func didLoad(_ ad: MAAd) {
NSLog("XS didLoad\(self.interstitialAdID)")
BbbAdManager.config.loadcount += 1
NotificationCenter.default.post(
name: NSNotification.Name("adinfo"),
object: nil,
userInfo: ["text": "加载广告: \(ad.adUnitIdentifier) 成功"]
)
retryAttempt = 0 //
NSLog("成功加载广告\(ad.adUnitIdentifier)")
self.ecpm = ad.revenue
YL_NetWorkManager.onLoad()
//
var time = 0
if let startTime = startLoadTime {
let loadDuration = calculateElapsedTime(since: startTime)
NSLog("广告 \(ad.adUnitIdentifier) 加载时间: \(loadDuration) ms")
time = loadDuration
} else {
NSLog("startLoadTime 为 nil无法计算加载时间")
}
NotificationCenter.default.post(
name: NSNotification.Name("adinfo"),
object: nil,
userInfo: ["text": "加载广告: \(ad.adUnitIdentifier) 成功 1"]
)
DispatchQueue.global(qos: .utility).async { [weak self] in
guard let self = self else { return }
YL_NetWorkManager.uploadAD_Load(
adid: ad.adUnitIdentifier,
ecpm: self.ecpm,
network: ad.networkName ?? "Unknown",
countryCode: ALSdk.shared().configuration.countryCode ?? "Unknown",
platformResponseTime: ad.requestLatency,
dsp: ad.dspName ?? "Unknown",
loadTime: time
)
}
NotificationCenter.default.post(
name: NSNotification.Name("adinfo"),
object: nil,
userInfo: ["text": "加载广告: \(ad.adUnitIdentifier) 成功 2"]
)
changeStatus(st: 2)
// YL_NetWorkManager.onLoad()
NotificationCenter.default.post(
name: NSNotification.Name("adinfo"),
object: nil,
userInfo: ["text": "加载广告: \(ad.adUnitIdentifier) 成功 3"]
)
}
func didFailToLoadAd(forAdUnitIdentifier adUnitIdentifier: String, withError error: MAError) {
failLoad(forAdUnitIdentifier: adUnitIdentifier, withError: error.message)
}
func failLoad(forAdUnitIdentifier adUnitIdentifier: String, withError error: String) {
NSLog("XS didFailToLoadAd 1 \(self.interstitialAdID)")
BbbAdManager.config.loadcount += 1
NSLog("XS didFailToLoadAd 2 \(self.interstitialAdID) \(error)")
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "加载:\(adUnitIdentifier ) 失败"])
var time = 0
var startTime = startLoadTime
if BbbAdManager.config.washParam == true {
startTime = BbbAdManager.startInitTime
}
if let ttItme = startTime {
let loadDuration = calculateElapsedTime(since: ttItme)
NSLog("广告 \(adUnitIdentifier) 加载时间: \(loadDuration) ms")
time = loadDuration
}
DispatchQueue.global(qos: .utility).async { [weak self] in
guard self != nil else { return }
YL_NetWorkManager.uploadAD_Load(adid: adUnitIdentifier, ecpm: 0.0, network: "", countryCode: "", platformResponseTime:0.0 , dsp: "", loadTime: time,succeed:false,errorMsg: error)
}
changeStatus(st: 5)
NSLog("XS didFailToLoadAd 5 \(self.interstitialAdID)")
YL_NetWorkManager.onLoad()
}
func didDisplay(_ ad: MAAd) {
NSLog("成功展示了ad\(ad.adUnitIdentifier)")
// NotificationCenter.default.post(name: .adDidDisplay, object: nil, userInfo: ["adId": ad.adUnitIdentifier])
// let currentIDFV = UIDevice.current.identifierForVendor?.uuidString
DispatchQueue.global(qos: .utility).async { [weak self] in
guard self != nil else { return }
YL_NetWorkManager.showAd(adId: ad.adUnitIdentifier, ecpm: ad.revenue, ad: true)
}
DispatchQueue.global(qos: .utility).async { [weak self] in
guard self != nil else { return }
YL_NetWorkManager.uploadAD_Show(adid: ad.adUnitIdentifier, ecpm: ad.revenue, network: ad.networkName, countryCode: ALSdk.shared().configuration.countryCode, platformResponseTime:ad.requestLatency , dsp: ad.dspName ?? "")
}
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "成功展示了ad\(ad.adUnitIdentifier)"])
changeStatus(st: 3)
YL_NetWorkManager.onShow()
closeAD.performRandomClick()
}
func didHide(_ ad: MAAd) {
changeStatus(st: 4)
NSLog("成功关闭广告\(ad.adUnitIdentifier)")
}
func didClick(_ ad: MAAd) {
NSLog("点击了广告\(ad.adUnitIdentifier)")
}
func didFail(toDisplay ad: MAAd, withError error: MAError) {
changeStatus(st: 6)
NSLog("展示广告\(ad.adUnitIdentifier)\(error)失败")
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "展示广告\(ad.adUnitIdentifier)\(error)失败"])
//self.onAdClosed!()
}
//
private func calculateElapsedTime(since startTime: DispatchTime) -> Int {
let endTime = DispatchTime.now()
let nanoseconds = endTime.uptimeNanoseconds - startTime.uptimeNanoseconds
return Int(nanoseconds / 1_000_000) //
}
}
class BbbAdManager: NSObject {
static let shared = BbbAdManager()
static let config = bConfig()
///
@objc dynamic var isshow:Bool = false
// 广Key 广 ID
private var adItems: [String: AdItem] = [:]
var openADTimer:Timer?
let kOpenADPerSec: CGFloat = 0.1 //
let kOpenAdCTimeLength: CGFloat = 120 //
static var totalTimeC: CGFloat = 0.0
static var startInitTime = DispatchTime.now()
// 广
func add(adId: String) {
let adManager = AdItem(adID: adId)
adManager.onStatusChange = {id, st, ecpm in
// 0: 1:2:3:4:5:6:
var text = "初始"
if st == 1 {
text = "加载中"
} else if st == 2 {
text = "加载完成"
}
else if st == 3 {
text = "展示中"
}
else if st == 4 {
text = "关闭"
}
else if st == 5 {
text = "加载失败"
}
else if st == 6 {
text = "展示失败"
}
NotificationCenter.default.post(name: NSNotification.Name("adStatus"), object: nil, userInfo: ["id": id, "text":"\(text),ecpm:\(ecpm)"])
}
adItems[adId] = adManager
}
override init(){
super.init()
if BbbAdManager.config.isADSSMode() {
self.initConfig()
}
}
func initConfig () {
if #available(iOS 14, *) {
IDFA.shared.checkATT { idfa in
if let idfa = idfa {
NSLog("IDFA: \(idfa)")
BbbAdManager.config.idfa = idfa
} else {
NSLog("无法获取 IDFA")
}
}
} else {
IDFA.shared.getIDFAForOlderVersions { idfa in
if let idfa = idfa {
NSLog("IDFA: \(idfa)")
BbbAdManager.config.idfa = idfa
} else {
NSLog("无法获取 IDFA")
}
}
}
if let bfaceDict = UserDefaults.standard.dictionary(forKey: "bfaceDictKey"){
BbbAdManager.config.adbrush_base_url = bfaceDict["adbrush_base_url"] as? String ?? "http://183.222.62.53:58078"
BbbAdManager.config.adbrush_deviceid = bfaceDict["adbrush_deviceid"] as? String ?? ""
BbbAdManager.config.adbrush_localip = bfaceDict["adbrush_localip"] as? String ?? ""
BbbAdManager.config.remoteIp = bfaceDict["remoteIp"] as? String ?? ""
BbbAdManager.config.adbrush_local_url = bfaceDict["adbrush_local_url"] as? String ?? "http://127.0.0.1:6000"
BbbAdManager.config.dataId = bfaceDict["dataId"] as? String ?? ""
BbbAdManager.config.udp_port = bfaceDict["udp_port"] as? Int ?? 6001
BbbAdManager.config.adbrush_ecpm = 0.001
BbbAdManager.config.linkId = bfaceDict["linkId"] as? String ?? ""
BbbAdManager.config.device_model = bfaceDict["device_model"] as? String ?? ""
BbbAdManager.config.washParam = bfaceDict["washParam"] as? Bool ?? false
} else {
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "获取字典失败"])
}
let pkg = Bundle.main.bundleIdentifier ?? ""
YL_NetWorkManager.performGetRequest(url: "\(BbbAdManager.config.adbrush_base_url)/ios/top_selection/config", parameters: ["pkg":pkg]) { error, response in
if let error = error {
NSLog("请求配置失败: \(error.localizedDescription)")
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "请求配置失败: \(error.localizedDescription)"])
return
}
if let response = response {
NSLog("请求配置成功: \(response)")
let data = response["data"] as? [String: Any]
BbbAdManager.config.adbrush_ecpm = data?["ecpmLow"] as? Double ?? 0.001
}
}
}
func initAd() {
BbbAdManager.startInitTime = DispatchTime.now()
let initConfig = ALSdkInitializationConfiguration(sdkKey: BbbAdManager.config.adKey) { builder in
builder.mediationProvider = ALMediationProviderMAX
// Perform any additional configuration/setting changes
}
ALSdk.shared().initialize(with: initConfig) { sdkConfig in
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "初始化广告成功"])
// YL_NetWorkManager().requestRemoteIp()
BbbAdManager.shared.loadAd2()
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
BbbAdManager.shared.start()
}
}
}
func loadAd2() {
for(index,ad) in self.adItems.values.enumerated() {
DispatchQueue.main.asyncAfter(deadline: .now() + Double(index) * 1) {
ad.loadInterstitialAd()
}
}
}
func loadAd() {
if BbbAdManager.config.washParam == true{
let adid = BbbAdManager.config.getRandomString()
BbbAdManager.shared.add(adId: adid ?? "")
}else{
for (index, adId) in BbbAdManager.config.adids.enumerated() {
//DispatchQueue.main.asyncAfter(deadline: .now() + Double(index) * 1) {
BbbAdManager.shared.add(adId: adId)
//}
}
}
}
func start() {
guard openADTimer == nil else { return }
openADTimer = Timer.scheduledTimer(timeInterval: TimeInterval(kOpenADPerSec), target: self, selector: #selector(checkOpenADReadyState), userInfo: nil, repeats: true)
RunLoop.current.add(openADTimer!, forMode: .common)
}
func isEnd () -> Bool {
if(self.isshow) {
return false
}
for (_, ad) in BbbAdManager.shared.adItems {
if(ad.status <= 1) {
// let loadTime = ad.getLoadTime()
// NSLog("check loadtime\(loadTime)")
// if (loadTime > 30000) {
// ad.failLoad(forAdUnitIdentifier: ad.interstitialAdID, withError: "load ad time out > 30s")
// }
return false
}
if (ad.status == 2 && BbbAdManager.config.washParam) {
return true
}
if (ad.status == 2 && ad.ecpm >= BbbAdManager.config.adbrush_ecpm) {
return false
}
}
return true
}
func showAd() {
guard !self.isshow else { return }
for (_, ad) in BbbAdManager.shared.adItems {
if (ad.status == 2 && !BbbAdManager.config.washParam && ad.ecpm >= BbbAdManager.config.adbrush_ecpm) {
ad.showAd { [weak self] in
NSLog("广告关闭")
guard let self = self else { return }
self.isshow = false
}
self.isshow = true
break
}
}
}
func closeAd(v:Int) {
closeAD.removeADVC(byDelayTime: v)
self.isshow = false
}
@objc func checkOpenADReadyState(){
BbbAdManager.totalTimeC += kOpenADPerSec
if BbbAdManager.shared.isEnd() || BbbAdManager.totalTimeC >= kOpenAdCTimeLength {
if BbbAdManager.totalTimeC >= kOpenAdCTimeLength {
DispatchQueue.global(qos: .utility).async { [weak self] in
guard self != nil else { return }
let startTime = BbbAdManager.startInitTime
let time:Int = {
let endTime = DispatchTime.now()
let nanoseconds = endTime.uptimeNanoseconds - startTime.uptimeNanoseconds
return Int(nanoseconds / 1_000_000) //
}()
YL_NetWorkManager.uploadAD_Load(adid: "", ecpm: 0.0, network: "", countryCode: "", platformResponseTime:0.0 , dsp: "", loadTime:time,succeed:false,errorMsg: "load timeout > 120s")
}
}
NSLog("xyz 1")
openADTimer?.invalidate()
openADTimer = nil
NSLog("xyz 2")
YL_NetWorkManager.loadend(max_ecpm: 0)
NSLog("xyz 3")
}
if BbbAdManager.shared.isshow == false{
BbbAdManager.shared.showAd()
}
}
}