横幅广告

This commit is contained in:
zeng 2025-07-11 14:49:02 +08:00
parent c3104280ea
commit ffc984babe
6 changed files with 162 additions and 7 deletions

View File

@ -282,6 +282,7 @@
1BF513112E1FA138009750EA /* SPStatAdModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF513102E1FA138009750EA /* SPStatAdModel.swift */; }; 1BF513112E1FA138009750EA /* SPStatAdModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF513102E1FA138009750EA /* SPStatAdModel.swift */; };
1BF513142E1FB8C1009750EA /* SPAppOpenAdManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF513132E1FB8C1009750EA /* SPAppOpenAdManager.swift */; }; 1BF513142E1FB8C1009750EA /* SPAppOpenAdManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF513132E1FB8C1009750EA /* SPAppOpenAdManager.swift */; };
1BF513162E20ADB4009750EA /* SPAppOpenAdViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF513152E20ADB4009750EA /* SPAppOpenAdViewController.swift */; }; 1BF513162E20ADB4009750EA /* SPAppOpenAdViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF513152E20ADB4009750EA /* SPAppOpenAdViewController.swift */; };
1BF513192E20DC85009750EA /* SPBannerAd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF513182E20DC85009750EA /* SPBannerAd.swift */; };
C3D1CE788CA03A1878493356 /* Pods_ThimraTV.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B64805795B479324EB764157 /* Pods_ThimraTV.framework */; }; C3D1CE788CA03A1878493356 /* Pods_ThimraTV.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B64805795B479324EB764157 /* Pods_ThimraTV.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@ -595,6 +596,7 @@
1BF513102E1FA138009750EA /* SPStatAdModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPStatAdModel.swift; sourceTree = "<group>"; }; 1BF513102E1FA138009750EA /* SPStatAdModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPStatAdModel.swift; sourceTree = "<group>"; };
1BF513132E1FB8C1009750EA /* SPAppOpenAdManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPAppOpenAdManager.swift; sourceTree = "<group>"; }; 1BF513132E1FB8C1009750EA /* SPAppOpenAdManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPAppOpenAdManager.swift; sourceTree = "<group>"; };
1BF513152E20ADB4009750EA /* SPAppOpenAdViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPAppOpenAdViewController.swift; sourceTree = "<group>"; }; 1BF513152E20ADB4009750EA /* SPAppOpenAdViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPAppOpenAdViewController.swift; sourceTree = "<group>"; };
1BF513182E20DC85009750EA /* SPBannerAd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPBannerAd.swift; sourceTree = "<group>"; };
1DBC40592DA4EDFC0093FCB0 /* ThimraTV.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ThimraTV.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1DBC40592DA4EDFC0093FCB0 /* ThimraTV.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ThimraTV.app; sourceTree = BUILT_PRODUCTS_DIR; };
1F666DE0B12C863F26BE5027 /* Pods-MoviaBox.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MoviaBox.debug.xcconfig"; path = "Target Support Files/Pods-MoviaBox/Pods-MoviaBox.debug.xcconfig"; sourceTree = "<group>"; }; 1F666DE0B12C863F26BE5027 /* Pods-MoviaBox.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MoviaBox.debug.xcconfig"; path = "Target Support Files/Pods-MoviaBox/Pods-MoviaBox.debug.xcconfig"; sourceTree = "<group>"; };
A1174E10BCF2C606F7818792 /* Pods-ThimraTV.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ThimraTV.release.xcconfig"; path = "Target Support Files/Pods-ThimraTV/Pods-ThimraTV.release.xcconfig"; sourceTree = "<group>"; }; A1174E10BCF2C606F7818792 /* Pods-ThimraTV.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ThimraTV.release.xcconfig"; path = "Target Support Files/Pods-ThimraTV/Pods-ThimraTV.release.xcconfig"; sourceTree = "<group>"; };
@ -1485,6 +1487,7 @@
1BDE20112E1E158400C2C2B5 /* AdManager */ = { 1BDE20112E1E158400C2C2B5 /* AdManager */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
1BF513172E20DC63009750EA /* BannerAd */,
1BF513122E1FB897009750EA /* AppOpenAd */, 1BF513122E1FB897009750EA /* AppOpenAd */,
1BF5130F2E1F5EE4009750EA /* RewardedAd */, 1BF5130F2E1F5EE4009750EA /* RewardedAd */,
1BDE20122E1E159B00C2C2B5 /* SPAdManager.swift */, 1BDE20122E1E159B00C2C2B5 /* SPAdManager.swift */,
@ -1512,6 +1515,14 @@
path = AppOpenAd; path = AppOpenAd;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
1BF513172E20DC63009750EA /* BannerAd */ = {
isa = PBXGroup;
children = (
1BF513182E20DC85009750EA /* SPBannerAd.swift */,
);
path = BannerAd;
sourceTree = "<group>";
};
1DBC40502DA4EDFC0093FCB0 = { 1DBC40502DA4EDFC0093FCB0 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -1831,6 +1842,7 @@
1BF5130C2E1F4660009750EA /* SPRewardedAdManager+AppLovin.swift in Sources */, 1BF5130C2E1F4660009750EA /* SPRewardedAdManager+AppLovin.swift in Sources */,
1BB91D712E04FD6A00A2C715 /* SPHomeHotView.swift in Sources */, 1BB91D712E04FD6A00A2C715 /* SPHomeHotView.swift in Sources */,
1BB91D722E04FD6A00A2C715 /* SPHomeNineSquareContentCell.swift in Sources */, 1BB91D722E04FD6A00A2C715 /* SPHomeNineSquareContentCell.swift in Sources */,
1BF513192E20DC85009750EA /* SPBannerAd.swift in Sources */,
1BB91D732E04FD6A00A2C715 /* SPHomePlayHistoricalView.swift in Sources */, 1BB91D732E04FD6A00A2C715 /* SPHomePlayHistoricalView.swift in Sources */,
1BDE20172E1E164600C2C2B5 /* SPAdAPI.swift in Sources */, 1BDE20172E1E164600C2C2B5 /* SPAdAPI.swift in Sources */,
1BB91D742E04FD6A00A2C715 /* SPHomePlayHistoryCell.swift in Sources */, 1BB91D742E04FD6A00A2C715 /* SPHomePlayHistoryCell.swift in Sources */,

View File

@ -164,6 +164,7 @@ class SPPlayerDetailViewController: SPPlayerListViewController {
guard let self = self else { return } guard let self = self else { return }
self._handleBack() self._handleBack()
if SPLoginManager.manager.userInfo?.user_level == .ad {
let manager = SPRewardedAdManager.manager let manager = SPRewardedAdManager.manager
manager.delegate = nil manager.delegate = nil
manager.statScene = .detail manager.statScene = .detail
@ -171,6 +172,7 @@ class SPPlayerDetailViewController: SPPlayerListViewController {
if manager.isAdAvailable() { if manager.isAdAvailable() {
manager.loadAndShowRewardedAd() manager.loadAndShowRewardedAd()
} }
}
} }

View File

@ -28,6 +28,11 @@ class SPPlayerDetailRecommandView: HWPanModalContentView {
} }
} }
private lazy var bannerAd: SPBannerAd = {
let ad = SPBannerAd()
return ad
}()
//MARK: UI //MARK: UI
private lazy var bgImageView: UIImageView = { private lazy var bgImageView: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "recommand_bg_image_01")) let imageView = UIImageView(image: UIImage(named: "recommand_bg_image_01"))
@ -102,8 +107,12 @@ class SPPlayerDetailRecommandView: HWPanModalContentView {
//MARK: HWPanModalPresentable //MARK: HWPanModalPresentable
override func longFormHeight() -> PanModalHeight { override func longFormHeight() -> PanModalHeight {
if SPLoginManager.manager.userInfo?.user_level == .ad {
return PanModalHeightMake(.content, 540 + bannerAd.size.height + kSPTabbarSafeBottomMargin)
} else {
return PanModalHeightMake(.content, 540 + kSPTabbarSafeBottomMargin) return PanModalHeightMake(.content, 540 + kSPTabbarSafeBottomMargin)
} }
}
override func showDragIndicator() -> Bool { override func showDragIndicator() -> Bool {
return false return false
@ -195,6 +204,17 @@ extension SPPlayerDetailRecommandView {
make.top.equalTo(bannerView.snp.bottom).offset(81) make.top.equalTo(bannerView.snp.bottom).offset(81)
make.height.equalTo(46) make.height.equalTo(46)
} }
if SPLoginManager.manager.userInfo?.user_level == .ad {
addSubview(bannerAd.view)
bannerAd.view.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.bottom.equalToSuperview().offset(-kSPTabbarSafeBottomMargin)
}
}
} }
} }

View File

@ -36,6 +36,15 @@ class SPAppOpenAdManager: NSObject {
static let manager = SPAppOpenAdManager() 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() { private func loadAd() {
// Do not load ad if there is an unused ad or one is already loading. // Do not load ad if there is an unused ad or one is already loading.
if isLoadingAd || isAdAvailable() { if isLoadingAd || isAdAvailable() {

View File

@ -0,0 +1,111 @@
//
// SPBannerAd.swift
// ThimraTV
//
// Created by on 2025/7/11.
//
import UIKit
import GoogleMobileAds
@objc protocol SPBannerAdDelegate: NSObjectProtocol {
///广
@objc optional func bannerAd(bannerAd: SPBannerAd, didLoadFail error: Error)
///广
@objc optional func bannerAdDidLoadFinish(bannerAd: SPBannerAd)
///广
@objc optional func bannerAdDidShow(bannerAd: SPBannerAd)
///广
@objc optional func bannerAdDidDismiss(bannerAd: SPBannerAd)
}
class SPBannerAd: NSObject {
#if DEBUG
let adUnitID = "ca-app-pub-3940256099942544/2435281174"
#endif
let size = CGSize.init(width: kSPScreenWidth, height: 59)
weak var delegate: SPBannerAdDelegate?
private(set) lazy var view: BannerView = {
let view = BannerView()
view.adUnitID = self.adUnitID
view.adSize = inlineAdaptiveBanner(width: size.width, maxHeight:size.height)
// view.adSize = adSizeFor(cgSize: size)
view.delegate = self
return view
}()
deinit {
NotificationCenter.default.removeObserver(self)
}
override init() {
super.init()
NotificationCenter.default.addObserver(self, selector: #selector(didEnterBackgroundNotification), name: UIApplication.didEnterBackgroundNotification, object: nil)
view.load(Request())
}
}
//MARK: -------------- BannerViewDelegate --------------
extension SPBannerAd: BannerViewDelegate {
func bannerViewDidReceiveAd(_ bannerView: BannerView) {
self.delegate?.bannerAdDidLoadFinish?(bannerAd: self)
}
func bannerView(_ bannerView: BannerView, didFailToReceiveAdWithError error: Error) {
self.requestStatAd(type: "load_failed", errorMsg: error.localizedDescription)
self.delegate?.bannerAd?(bannerAd: self, didLoadFail: error)
}
func bannerViewDidRecordClick(_ bannerView: BannerView) {
print(#function)
self.requestStatAd(type: "click", errorMsg: nil)
}
func bannerViewDidRecordImpression(_ bannerView: BannerView) {
print(#function)
}
func bannerViewWillPresentScreen(_ bannerView: BannerView) {
self.requestStatAd(type: "start", errorMsg: nil)
self.delegate?.bannerAdDidShow?(bannerAd: self)
}
func bannerViewWillDismissScreen(_ bannerView: BannerView) {
print(#function)
}
func bannerViewDidDismissScreen(_ bannerView: BannerView) {
self.requestStatAd(type: "close", errorMsg: nil)
self.delegate?.bannerAdDidDismiss?(bannerAd: self)
}
}
//MARK: -------------- --------------
extension SPBannerAd {
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() {
self.requestStatAd(type: "Interrupt", errorMsg: nil)
}
}

View File

@ -15,6 +15,7 @@ class SPStatAdModel: SPModel, SmartCodable {
case me = "me" case me = "me"
case reward = "reward" case reward = "reward"
case splash = "splash" case splash = "splash"
case banner = "banner"
} }
var type: String? //start click error click show_failed load_failed Interrupt(退) close var type: String? //start click error click show_failed load_failed Interrupt(退) close