1.1.3提审

This commit is contained in:
zeng 2025-07-16 17:06:13 +08:00
parent a6219af9ed
commit de51890ff7
20 changed files with 1334 additions and 879 deletions

View File

@ -282,7 +282,11 @@
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 */; }; 1BF513192E20DC85009750EA /* SPBannerAdManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF513182E20DC85009750EA /* SPBannerAdManager.swift */; };
1BF5131B2E265880009750EA /* SPAdmobAppOpenAd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF5131A2E265880009750EA /* SPAdmobAppOpenAd.swift */; };
1BF5131D2E265A80009750EA /* SPApplovinAppOpenAd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF5131C2E265A80009750EA /* SPApplovinAppOpenAd.swift */; };
1BF513212E2662DC009750EA /* SPAdmobBannerAd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF513202E2662DC009750EA /* SPAdmobBannerAd.swift */; };
1BF513232E273482009750EA /* SPApplovinBannerAd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF513222E273479009750EA /* SPApplovinBannerAd.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 */
@ -596,7 +600,11 @@
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>"; }; 1BF513182E20DC85009750EA /* SPBannerAdManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPBannerAdManager.swift; sourceTree = "<group>"; };
1BF5131A2E265880009750EA /* SPAdmobAppOpenAd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPAdmobAppOpenAd.swift; sourceTree = "<group>"; };
1BF5131C2E265A80009750EA /* SPApplovinAppOpenAd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPApplovinAppOpenAd.swift; sourceTree = "<group>"; };
1BF513202E2662DC009750EA /* SPAdmobBannerAd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPAdmobBannerAd.swift; sourceTree = "<group>"; };
1BF513222E273479009750EA /* SPApplovinBannerAd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPApplovinBannerAd.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>"; };
@ -1511,6 +1519,8 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
1BF513132E1FB8C1009750EA /* SPAppOpenAdManager.swift */, 1BF513132E1FB8C1009750EA /* SPAppOpenAdManager.swift */,
1BF5131A2E265880009750EA /* SPAdmobAppOpenAd.swift */,
1BF5131C2E265A80009750EA /* SPApplovinAppOpenAd.swift */,
); );
path = AppOpenAd; path = AppOpenAd;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1518,7 +1528,9 @@
1BF513172E20DC63009750EA /* BannerAd */ = { 1BF513172E20DC63009750EA /* BannerAd */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
1BF513182E20DC85009750EA /* SPBannerAd.swift */, 1BF513182E20DC85009750EA /* SPBannerAdManager.swift */,
1BF513202E2662DC009750EA /* SPAdmobBannerAd.swift */,
1BF513222E273479009750EA /* SPApplovinBannerAd.swift */,
); );
path = BannerAd; path = BannerAd;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1743,6 +1755,7 @@
1BB91D132E04FD6A00A2C715 /* AppDelegate+OpenApp.swift in Sources */, 1BB91D132E04FD6A00A2C715 /* AppDelegate+OpenApp.swift in Sources */,
1BB91D142E04FD6A00A2C715 /* AppDelegate+Thirdparty.swift in Sources */, 1BB91D142E04FD6A00A2C715 /* AppDelegate+Thirdparty.swift in Sources */,
1BB91D152E04FD6A00A2C715 /* SceneDelegate.swift in Sources */, 1BB91D152E04FD6A00A2C715 /* SceneDelegate.swift in Sources */,
1BF5131D2E265A80009750EA /* SPApplovinAppOpenAd.swift in Sources */,
1BB91D162E04FD6A00A2C715 /* SPNavigationController.swift in Sources */, 1BB91D162E04FD6A00A2C715 /* SPNavigationController.swift in Sources */,
1BB91D172E04FD6A00A2C715 /* SPTabBarController.swift in Sources */, 1BB91D172E04FD6A00A2C715 /* SPTabBarController.swift in Sources */,
1BB91D182E04FD6A00A2C715 /* SPViewController.swift in Sources */, 1BB91D182E04FD6A00A2C715 /* SPViewController.swift in Sources */,
@ -1776,6 +1789,7 @@
1BC1F0D72E0A35EF00B579A4 /* SPVideoRevolutionManager.swift in Sources */, 1BC1F0D72E0A35EF00B579A4 /* SPVideoRevolutionManager.swift in Sources */,
1BB91D342E04FD6A00A2C715 /* SPSettingAPI.swift in Sources */, 1BB91D342E04FD6A00A2C715 /* SPSettingAPI.swift in Sources */,
1BB91D352E04FD6A00A2C715 /* SPStatAPI.swift in Sources */, 1BB91D352E04FD6A00A2C715 /* SPStatAPI.swift in Sources */,
1BF5131B2E265880009750EA /* SPAdmobAppOpenAd.swift in Sources */,
1BB91D362E04FD6A00A2C715 /* SPUserAPI.swift in Sources */, 1BB91D362E04FD6A00A2C715 /* SPUserAPI.swift in Sources */,
1BB91D372E04FD6A00A2C715 /* SPVideoAPI.swift in Sources */, 1BB91D372E04FD6A00A2C715 /* SPVideoAPI.swift in Sources */,
1BB91D382E04FD6A00A2C715 /* SPWalletAPI.swift in Sources */, 1BB91D382E04FD6A00A2C715 /* SPWalletAPI.swift in Sources */,
@ -1817,6 +1831,7 @@
1BB91D5A2E04FD6A00A2C715 /* SPHomePageController.swift in Sources */, 1BB91D5A2E04FD6A00A2C715 /* SPHomePageController.swift in Sources */,
1BB91D5B2E04FD6A00A2C715 /* SPHomeV2ViewController.swift in Sources */, 1BB91D5B2E04FD6A00A2C715 /* SPHomeV2ViewController.swift in Sources */,
1BDE201E2E1E3D3E00C2C2B5 /* SPRewardedAdManager+Admob.swift in Sources */, 1BDE201E2E1E3D3E00C2C2B5 /* SPRewardedAdManager+Admob.swift in Sources */,
1BF513212E2662DC009750EA /* SPAdmobBannerAd.swift in Sources */,
1BB91D5C2E04FD6A00A2C715 /* SPHomeViewController.swift in Sources */, 1BB91D5C2E04FD6A00A2C715 /* SPHomeViewController.swift in Sources */,
1BB91D5D2E04FD6A00A2C715 /* SPSearchViewController.swift in Sources */, 1BB91D5D2E04FD6A00A2C715 /* SPSearchViewController.swift in Sources */,
1BB91D5E2E04FD6A00A2C715 /* SPHomeCategoryModel.swift in Sources */, 1BB91D5E2E04FD6A00A2C715 /* SPHomeCategoryModel.swift in Sources */,
@ -1842,7 +1857,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 */, 1BF513192E20DC85009750EA /* SPBannerAdManager.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 */,
@ -1964,6 +1979,7 @@
1BB91DE42E04FD6A00A2C715 /* SPTokenModel.swift in Sources */, 1BB91DE42E04FD6A00A2C715 /* SPTokenModel.swift in Sources */,
1BB91DE52E04FD6A00A2C715 /* SPPlayer.swift in Sources */, 1BB91DE52E04FD6A00A2C715 /* SPPlayer.swift in Sources */,
1BB91DE62E04FD6A00A2C715 /* SPIAPManager.swift in Sources */, 1BB91DE62E04FD6A00A2C715 /* SPIAPManager.swift in Sources */,
1BF513232E273482009750EA /* SPApplovinBannerAd.swift in Sources */,
1BB91DE72E04FD6A00A2C715 /* SPIAPOrderModel.swift in Sources */, 1BB91DE72E04FD6A00A2C715 /* SPIAPOrderModel.swift in Sources */,
1BB91DE82E04FD6A00A2C715 /* SPIAPVerifyModel.swift in Sources */, 1BB91DE82E04FD6A00A2C715 /* SPIAPVerifyModel.swift in Sources */,
1BB91DE92E04FD6A00A2C715 /* SPWaitRestoreModel.swift in Sources */, 1BB91DE92E04FD6A00A2C715 /* SPWaitRestoreModel.swift in Sources */,
@ -2098,7 +2114,7 @@
CODE_SIGN_ENTITLEMENTS = ThimraTV/ThimraTV.entitlements; CODE_SIGN_ENTITLEMENTS = ThimraTV/ThimraTV.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2; CURRENT_PROJECT_VERSION = 5;
DEVELOPMENT_TEAM = TWDZ3MP9DV; DEVELOPMENT_TEAM = TWDZ3MP9DV;
ENABLE_USER_SCRIPT_SANDBOXING = NO; ENABLE_USER_SCRIPT_SANDBOXING = NO;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@ -2146,7 +2162,7 @@
CODE_SIGN_ENTITLEMENTS = ThimraTV/ThimraTV.entitlements; CODE_SIGN_ENTITLEMENTS = ThimraTV/ThimraTV.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2; CURRENT_PROJECT_VERSION = 5;
DEVELOPMENT_TEAM = TWDZ3MP9DV; DEVELOPMENT_TEAM = TWDZ3MP9DV;
ENABLE_USER_SCRIPT_SANDBOXING = NO; ENABLE_USER_SCRIPT_SANDBOXING = NO;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;

View File

@ -12,8 +12,13 @@ import FirebaseCore
extension AppDelegate { extension AppDelegate {
/// ///
static var haveBeenShownAPNS = false static var haveBeenShownAPNS = false
///
static var isRequestAuthorization = false
func registerAPNS() { func registerAPNS() {
guard !Self.isRequestAuthorization else { return }
Self.isRequestAuthorization = true
FirebaseApp.configure() FirebaseApp.configure()
Messaging.messaging().delegate = self Messaging.messaging().delegate = self

View File

@ -30,7 +30,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
// SPLoginManager.manager.requestVisitorLogin(completer: nil) // SPLoginManager.manager.requestVisitorLogin(completer: nil)
SPLoginManager.manager.updateUserInfo(completer: nil) SPLoginManager.manager.updateUserInfo(completer: nil)
/// ///
registerAPNS() // registerAPNS()
return true return true
} }

View File

@ -122,16 +122,20 @@ extension SceneDelegate {
window?.rootViewController = guideVc window?.rootViewController = guideVc
window?.makeKeyAndVisible() window?.makeKeyAndVisible()
SPAPPTool.appDelegate?.registerAPNS()
} else if SPLoginManager.manager.userInfo?.user_level == .ad, !SPAPPTool.isAppOpen, hasOpenApp == true, SPNetworkReachabilityManager.manager.isReachable == true { //广 } else if SPLoginManager.manager.userInfo?.user_level == .ad, !SPAPPTool.isAppOpen, hasOpenApp == true, SPNetworkReachabilityManager.manager.isReachable == true { //广
let openAdVC = SPAppOpenAdViewController() let openAdVC = SPAppOpenAdViewController()
openAdVC.didEndBlock = { [weak self] in openAdVC.didEndBlock = { [weak self] in
self?.handleOpenApp() self?.handleOpenApp()
SPAPPTool.appDelegate?.registerAPNS()
} }
window?.rootViewController = openAdVC window?.rootViewController = openAdVC
window?.makeKeyAndVisible() window?.makeKeyAndVisible()
} else { } else {
handleOpenApp() handleOpenApp()
SPAPPTool.appDelegate?.registerAPNS()
} }
} }

View File

@ -32,20 +32,28 @@ class SPAppOpenAdViewController: SPViewController {
private func openApp() {
self.didEndBlock?()
NotificationCenter.default.post(name: SPGuideViewController.didOpenAppNotification, object: nil, userInfo: nil)
}
} }
extension SPAppOpenAdViewController: SPAppOpenAdManagerDelegate { extension SPAppOpenAdViewController: SPAppOpenAdManagerDelegate {
///广 ///广
func appOpenAdManager(manager: SPAppOpenAdManager, didLoadFail error: Error) { func appOpenAdManager(manager: SPAppOpenAdManager, didLoadFail error: Error) {
self.didEndBlock?() openApp()
} }
///广 ///广
func appOpenAdManager(manager: SPAppOpenAdManager, didDisplayFail error: Error) { func appOpenAdManager(manager: SPAppOpenAdManager, didDisplayFail error: Error) {
self.didEndBlock?() openApp()
} }
///广 ///广
func appOpenAdManagerDidDismiss(manager: SPAppOpenAdManager) { func appOpenAdManagerDidDismiss(manager: SPAppOpenAdManager) {
self.didEndBlock?() openApp()
}
func appOpenAdManager(manager: SPAppOpenAdManager, didOtherFail error: any Error) {
openApp()
} }
} }

View File

@ -17,9 +17,18 @@ class SPVersionUpdateModel: SPModel, SmartCodable {
func canUpdate() -> Bool { func canUpdate() -> Bool {
let currentCode = NSNumber(string: kSPAPPBundleVersion)?.intValue ?? 0 // let currentCode = NSNumber(string: kSPAPPBundleVersion)?.intValue ?? 0
let serverCode = NSNumber(string: version_code ?? "0")?.intValue ?? 0 // let serverCode = NSNumber(string: version_code ?? "0")?.intValue ?? 0
return serverCode > currentCode // return serverCode > currentCode
guard let versionName = version_name else { return false }
let result = kSPAPPVersion.compare(versionName, options: .numeric)
if result == .orderedAscending {
return true
} else {
return false
}
} }

View File

@ -28,8 +28,8 @@ class SPPlayerDetailRecommandView: HWPanModalContentView {
} }
} }
private lazy var bannerAd: SPBannerAd = { private lazy var bannerAd: SPBannerAdManager = {
let ad = SPBannerAd() let ad = SPBannerAdManager()
return ad return ad
}() }()
@ -213,6 +213,7 @@ extension SPPlayerDetailRecommandView {
bannerAd.view.snp.makeConstraints { make in bannerAd.view.snp.makeConstraints { make in
make.centerX.equalToSuperview() make.centerX.equalToSuperview()
make.bottom.equalToSuperview().offset(-kSPTabbarSafeBottomMargin) make.bottom.equalToSuperview().offset(-kSPTabbarSafeBottomMargin)
make.size.equalTo(bannerAd.size)
} }
} }

View File

@ -128,11 +128,12 @@ extension SPPlayerListViewModel {
completer?(false) completer?(false)
case .success: case .success:
videoInfo?.is_lock = false
completer?(true)
// //
SPLoginManager.manager.updateUserInfo(completer: nil) SPLoginManager.manager.updateUserInfo {
videoInfo?.is_lock = false
completer?(true)
}
default: default:
completer?(false) completer?(false)

View File

@ -0,0 +1,67 @@
//
// SPAdmobAppOpenAd.swift
// ThimraTV
//
// Created by on 2025/7/15.
//
import UIKit
import GoogleMobileAds
class SPAdmobAppOpenAd: NSObject, SPAppOpenAd {
private var appOpenAd: AppOpenAd?
var delegate: (any SPAppOpenAdDelegate)?
var adPlatformKey: String {
return SPAdPlatformKey.google.rawValue
}
var adUnitID: String {
return SPAdManager.manager.admob_appOpenAdUnitID
}
var isReady: Bool {
return appOpenAd != nil
}
func loadAd() {
AppOpenAd.load(with: adUnitID, request: Request()) { [weak self] appOpenAd, error in
guard let self = self else { return }
self.appOpenAd = appOpenAd
self.appOpenAd?.fullScreenContentDelegate = self
if let error = error {
self.delegate?.appOpenAd?(ad: self, didLoadFail: error)
} else {
self.delegate?.appOpenAdDidLoadFinish?(ad: self)
}
}
}
func showAd() {
appOpenAd?.present(from: nil)
}
}
extension SPAdmobAppOpenAd: FullScreenContentDelegate {
func adWillPresentFullScreenContent(_ ad: FullScreenPresentingAd) {
self.delegate?.appOpenAdDidShow?(ad: self)
}
func adDidDismissFullScreenContent(_ ad: FullScreenPresentingAd) {
self.delegate?.appOpenAdDidDismiss?(ad: self)
}
func ad(_ ad: FullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {
self.delegate?.appOpenAd?(ad: self, didDisplayFail: error)
}
func adDidRecordClick(_ ad: any FullScreenPresentingAd) {
self.delegate?.appOpenAdDidClick?(ad: self)
}
}

View File

@ -6,7 +6,6 @@
// //
import UIKit import UIKit
import GoogleMobileAds
@objc protocol SPAppOpenAdManagerDelegate: NSObjectProtocol { @objc protocol SPAppOpenAdManagerDelegate: NSObjectProtocol {
///广 ///广
@ -19,21 +18,60 @@ import GoogleMobileAds
@objc optional func appOpenAdManagerDidShow(manager: SPAppOpenAdManager) @objc optional func appOpenAdManagerDidShow(manager: SPAppOpenAdManager)
///广 ///广
@objc optional func appOpenAdManagerDidDismiss(manager: SPAppOpenAdManager) @objc optional func appOpenAdManagerDidDismiss(manager: SPAppOpenAdManager)
///
@objc optional func appOpenAdManager(manager: SPAppOpenAdManager, didOtherFail error: Error)
}
@objc protocol SPAppOpenAdDelegate: NSObjectProtocol {
///广
@objc optional func appOpenAd(ad: SPAppOpenAd, didLoadFail error: Error)
///广
@objc optional func appOpenAdDidLoadFinish(ad: SPAppOpenAd)
///广
@objc optional func appOpenAd(ad: SPAppOpenAd, didDisplayFail error: Error)
///广
@objc optional func appOpenAdDidShow(ad: SPAppOpenAd)
///广
@objc optional func appOpenAdDidDismiss(ad: SPAppOpenAd)
///广
@objc optional func appOpenAdDidClick(ad: SPAppOpenAd)
}
@objc protocol SPAppOpenAd: NSObjectProtocol {
weak var delegate: SPAppOpenAdDelegate? { get set }
var adPlatformKey: String { get }
var adUnitID: String { get }
var isReady: Bool { get }
func loadAd()
func showAd()
} }
class SPAppOpenAdManager: NSObject { class SPAppOpenAdManager: NSObject {
static let manager = SPAppOpenAdManager()
weak var delegate: SPAppOpenAdManagerDelegate? weak var delegate: SPAppOpenAdManagerDelegate?
let adUnitID = SPAdManager.manager.appOpenAdUnitID let adUnitID = SPAdManager.manager.admob_appOpenAdUnitID
private var appOpenAd: SPAppOpenAd?
private var appOpenAd: AppOpenAd?
private(set) var isLoadingAd = false private(set) var isLoadingAd = false
private(set) var isShowingAd = false private(set) var isShowingAd = false
private var isNeedShow = false private var isNeedShow = false
static let manager = SPAppOpenAdManager() private var timeOutTimer: Timer?
deinit { deinit {
NotificationCenter.default.removeObserver(self) NotificationCenter.default.removeObserver(self)
@ -51,26 +89,17 @@ class SPAppOpenAdManager: NSObject {
} }
isLoadingAd = true isLoadingAd = true
AppOpenAd.load(with: adUnitID, request: Request()) { [weak self] appOpenAd, error in appOpenAd = SPAdmobAppOpenAd()
guard let self = self else { return } appOpenAd?.delegate = self
self.isLoadingAd = false appOpenAd?.loadAd()
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 showAd() {
if let ad = appOpenAd {
self.isNeedShow = false
isShowingAd = true
ad.showAd()
}
} }
func showAdIfAvailable() { func showAdIfAvailable() {
@ -79,6 +108,8 @@ class SPAppOpenAdManager: NSObject {
self.isNeedShow = true self.isNeedShow = true
self.timeOutTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(handleTimeOutTimer), userInfo: nil, repeats: false)
// If the app open ad is not available yet but is supposed to show, load // If the app open ad is not available yet but is supposed to show, load
// a new ad. // a new ad.
if !isAdAvailable() { if !isAdAvailable() {
@ -86,48 +117,80 @@ class SPAppOpenAdManager: NSObject {
return return
} }
if let ad = appOpenAd { showAd()
self.isNeedShow = false
isShowingAd = true
ad.present(from: nil)
}
} }
private func isAdAvailable() -> Bool { private func isAdAvailable() -> Bool {
// Check if ad exists and can be shown. return appOpenAd?.isReady ?? false
return appOpenAd != nil
}
} }
extension SPAppOpenAdManager: FullScreenContentDelegate { @objc private func handleTimeOutTimer() {
func adWillPresentFullScreenContent(_ ad: FullScreenPresentingAd) { self.isNeedShow = false
self.requestStatAd(type: "start", errorMsg: nil) self.timeOutTimer?.invalidate()
print("App open ad will be presented.") self.timeOutTimer = nil
self.delegate?.appOpenAdManagerDidShow?(manager: self) clearTimer()
let error = NSError(domain: "time-out", code: -1)
self.delegate?.appOpenAdManager?(manager: self, didOtherFail: error)
} }
func adDidDismissFullScreenContent(_ ad: FullScreenPresentingAd) { private func clearTimer() {
self.requestStatAd(type: "close", errorMsg: nil) self.timeOutTimer?.invalidate()
self.timeOutTimer = nil
appOpenAd = nil
isShowingAd = false
// Reload an ad.
// self.loadAd()
self.delegate?.appOpenAdManagerDidDismiss?(manager: self)
} }
func ad(_ ad: FullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) { }
//MARK: -------------- SPAppOpenAdDelegate --------------
extension SPAppOpenAdManager: SPAppOpenAdDelegate {
///广
func appOpenAd(ad: SPAppOpenAd, didLoadFail error: Error) {
self.requestStatAd(type: "load_failed", errorMsg: error.localizedDescription)
isLoadingAd = false
clearTimer()
self.delegate?.appOpenAdManager?(manager: self, didLoadFail: error)
}
///广
func appOpenAdDidLoadFinish(ad: SPAppOpenAd) {
isLoadingAd = false
clearTimer()
self.delegate?.appOpenAdManagerDidLoadFinish?(manager: self)
if isNeedShow {
self.showAd()
}
}
///广
func appOpenAd(ad: SPAppOpenAd, didDisplayFail error: Error) {
self.requestStatAd(type: "show_failed", errorMsg: error.localizedDescription) self.requestStatAd(type: "show_failed", errorMsg: error.localizedDescription)
appOpenAd = nil appOpenAd = nil
isShowingAd = false isShowingAd = false
// Reload an ad. clearTimer()
// self.loadAd()
self.delegate?.appOpenAdManager?(manager: self, didDisplayFail: error) self.delegate?.appOpenAdManager?(manager: self, didDisplayFail: error)
} }
///广
func appOpenAdDidShow(ad: SPAppOpenAd) {
self.requestStatAd(type: "start", errorMsg: nil)
self.delegate?.appOpenAdManagerDidShow?(manager: self)
}
///广
func appOpenAdDidDismiss(ad: SPAppOpenAd) {
self.requestStatAd(type: "close", errorMsg: nil)
func adDidRecordClick(_ ad: any FullScreenPresentingAd) { appOpenAd = nil
isShowingAd = false
self.delegate?.appOpenAdManagerDidDismiss?(manager: self)
}
///广
func appOpenAdDidClick(ad: SPAppOpenAd) {
self.requestStatAd(type: "click", errorMsg: nil) self.requestStatAd(type: "click", errorMsg: nil)
} }
@ -137,10 +200,12 @@ extension SPAppOpenAdManager: FullScreenContentDelegate {
extension SPAppOpenAdManager { extension SPAppOpenAdManager {
private func requestStatAd(type: String, errorMsg: String?) { private func requestStatAd(type: String, errorMsg: String?) {
guard let appOpenAd = appOpenAd else { return }
let model = SPStatAdModel() let model = SPStatAdModel()
model.type = type model.type = type
model.ads_id = adUnitID model.ads_id = appOpenAd.adUnitID
model.ad_platform_key = .google model.ad_platform_key = SPAdPlatformKey(rawValue: appOpenAd.adPlatformKey)
model.error_msg = errorMsg model.error_msg = errorMsg
model.scene = .splash model.scene = .splash
@ -149,7 +214,7 @@ extension SPAppOpenAdManager {
@objc private func didEnterBackgroundNotification() { @objc private func didEnterBackgroundNotification() {
guard appOpenAd != nil else { return } if !self.isShowingAd { return }
self.requestStatAd(type: "Interrupt", errorMsg: nil) self.requestStatAd(type: "Interrupt", errorMsg: nil)
} }

View File

@ -0,0 +1,79 @@
//
// SPApplovinAppOpenAd.swift
// ThimraTV
//
// Created by on 2025/7/15.
//
import UIKit
import AppLovinSDK
class SPApplovinAppOpenAd: NSObject, SPAppOpenAd {
private lazy var appOpenAd = MAAppOpenAd(adUnitIdentifier: adUnitID)
var delegate: (any SPAppOpenAdDelegate)?
var adPlatformKey: String {
return SPAdPlatformKey.applovin.rawValue
}
var adUnitID: String {
return SPAdManager.manager.applovin_appOpenAdUnitID
}
var isReady: Bool {
if ALSdk.shared().isInitialized && appOpenAd.isReady {
return true
} else {
return false
}
}
func loadAd() {
SPAdManager.manager.initialize_applovinSdk { [weak self] in
guard let self = self else { return }
appOpenAd.delegate = self
appOpenAd.load()
}
}
func showAd() {
guard isReady else { return }
appOpenAd.show()
}
}
//MARK: -------------- MAAdDelegate --------------
extension SPApplovinAppOpenAd: MAAdDelegate {
func didLoad(_ ad: MAAd) {
self.delegate?.appOpenAdDidLoadFinish?(ad: self)
}
func didFailToLoadAd(forAdUnitIdentifier adUnitIdentifier: String, withError error: MAError) {
let nsError = NSError(domain: error.message, code: error.code.rawValue)
self.delegate?.appOpenAd?(ad: self, didLoadFail: nsError)
}
func didDisplay(_ ad: MAAd) {
self.delegate?.appOpenAdDidShow?(ad: self)
}
func didHide(_ ad: MAAd) {
self.delegate?.appOpenAdDidDismiss?(ad: self)
}
func didClick(_ ad: MAAd) {
self.delegate?.appOpenAdDidClick?(ad: self)
}
func didFail(toDisplay ad: MAAd, withError error: MAError) {
let nsError = NSError(domain: error.message, code: error.code.rawValue)
self.delegate?.appOpenAd?(ad: self, didDisplayFail: nsError)
}
}

View File

@ -0,0 +1,75 @@
//
// SPAdmobBannerAd.swift
// ThimraTV
//
// Created by on 2025/7/15.
//
import UIKit
import GoogleMobileAds
class SPAdmobBannerAd: NSObject, SPBannerAd {
var delegate: (any SPBannerAdDelegate)?
let size = CGSize.init(width: kSPScreenWidth, height: 59)
private lazy var _adView: BannerView = {
let view = BannerView()
view.adUnitID = self.adUnitID
view.adSize = inlineAdaptiveBanner(width: size.width, maxHeight:size.height)
view.delegate = self
return view
}()
var adView: UIView {
return _adView
}
var adPlatformKey: String {
return SPAdPlatformKey.google.rawValue
}
var adUnitID: String {
return SPAdManager.manager.admob_bannerAdUnitID
}
func loadAd() {
_adView.load(Request())
}
}
//MARK: -------------- BannerViewDelegate --------------
extension SPAdmobBannerAd: BannerViewDelegate {
func bannerViewDidReceiveAd(_ bannerView: BannerView) {
self.delegate?.bannerAdDidLoadFinish?(bannerAd: self)
}
func bannerView(_ bannerView: BannerView, didFailToReceiveAdWithError error: Error) {
self.delegate?.bannerAd?(bannerAd: self, didLoadFail: error)
}
func bannerViewDidRecordClick(_ bannerView: BannerView) {
self.delegate?.bannerAdDidClick?(ad: self)
}
func bannerViewDidRecordImpression(_ bannerView: BannerView) {
}
func bannerViewWillPresentScreen(_ bannerView: BannerView) {
self.delegate?.bannerAdDidShow?(bannerAd: self)
}
func bannerViewWillDismissScreen(_ bannerView: BannerView) {
}
func bannerViewDidDismissScreen(_ bannerView: BannerView) {
self.delegate?.bannerAdDidDismiss?(bannerAd: self)
}
}

View File

@ -0,0 +1,82 @@
//
// SPApplovinBannerAd.swift
// ThimraTV
//
// Created by on 2025/7/16.
//
import UIKit
import AppLovinSDK
class SPApplovinBannerAd: NSObject, SPBannerAd {
let size = CGSize.init(width: kSPScreenWidth, height: 59)
var delegate: (any SPBannerAdDelegate)?
private(set) lazy var _adView: MAAdView = {
let view = MAAdView(adUnitIdentifier: adUnitID)
view.frame = .init(x: 0, y: 0, width: size.width, height: size.height)
view.delegate = self
return view
}()
var adView: UIView {
return _adView
}
var adPlatformKey: String {
return SPAdPlatformKey.applovin.rawValue
}
var adUnitID: String {
return SPAdManager.manager.applovin_bannerAdUnitID
}
func loadAd() {
_adView.loadAd()
}
}
//MARK: -------------- MAAdViewAdDelegate --------------
extension SPApplovinBannerAd: MAAdViewAdDelegate {
func didExpand(_ ad: MAAd) {
}
func didCollapse(_ ad: MAAd) {
}
func didLoad(_ ad: MAAd) {
self.delegate?.bannerAdDidLoadFinish?(bannerAd: self)
}
func didFailToLoadAd(forAdUnitIdentifier adUnitIdentifier: String, withError error: MAError) {
let nsError = NSError(domain: error.message, code: error.code.rawValue)
self.delegate?.bannerAd?(bannerAd: self, didLoadFail: nsError)
}
func didDisplay(_ ad: MAAd) {
self.delegate?.bannerAdDidShow?(bannerAd: self)
}
func didHide(_ ad: MAAd) {
self.delegate?.bannerAdDidDismiss?(bannerAd: self)
}
func didClick(_ ad: MAAd) {
self.delegate?.bannerAdDidClick?(ad: self)
}
func didFail(toDisplay ad: MAAd, withError error: MAError) {
}
}

View File

@ -1,111 +0,0 @@
//
// 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 {
let adUnitID = SPAdManager.manager.bannerAdUnitID
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.requestStatAd(type: "start", errorMsg: nil)
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.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 {
func requestStatAd(type: String, errorMsg: String?) {
guard self.view.superview != nil else { return }
let model = SPStatAdModel()
model.type = type
model.ads_id = adUnitID
model.ad_platform_key = .google
model.error_msg = errorMsg
model.scene = .banner
SPStatAPI.requestStatAd(model: model)
}
@objc private func didEnterBackgroundNotification() {
self.requestStatAd(type: "Interrupt", errorMsg: nil)
}
}

View File

@ -0,0 +1,135 @@
//
// SPBannerAdManager.swift
// ThimraTV
//
// Created by on 2025/7/11.
//
import UIKit
import GoogleMobileAds
@objc protocol SPBannerAdManagerDelegate: NSObjectProtocol {
///广
@objc optional func bannerAdManager(adManager: SPBannerAdManager, didLoadFail error: Error)
///广
@objc optional func bannerAdManagerDidLoadFinish(adManager: SPBannerAdManager)
///广
@objc optional func bannerAdManagerDidShow(adManager: SPBannerAdManager)
///广
@objc optional func bannerAdManagerDidDismiss(adManager: SPBannerAdManager)
}
@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)
///广
@objc optional func bannerAdDidClick(ad: SPBannerAd)
}
@objc protocol SPBannerAd: NSObjectProtocol {
weak var delegate: SPBannerAdDelegate? { get set }
var adView: UIView { get }
var adPlatformKey: String { get }
var adUnitID: String { get }
func loadAd()
}
class SPBannerAdManager: NSObject {
let adUnitID = SPAdManager.manager.admob_bannerAdUnitID
let size = CGSize.init(width: kSPScreenWidth, height: 59)
weak var delegate: SPBannerAdManagerDelegate?
private lazy var bannerAd: SPBannerAd = {
let ad = SPAdmobBannerAd()
ad.delegate = self
return ad
}()
var view: UIView {
return bannerAd.adView
}
deinit {
NotificationCenter.default.removeObserver(self)
}
override init() {
super.init()
NotificationCenter.default.addObserver(self, selector: #selector(didEnterBackgroundNotification), name: UIApplication.didEnterBackgroundNotification, object: nil)
bannerAd.loadAd()
}
}
//MARK: -------------- SPBannerAdDelegate --------------
extension SPBannerAdManager: SPBannerAdDelegate {
///广
func bannerAd(bannerAd: SPBannerAd, didLoadFail error: Error) {
self.requestStatAd(type: "load_failed", errorMsg: error.localizedDescription)
self.delegate?.bannerAdManager?(adManager: self, didLoadFail: error)
}
///广
func bannerAdDidLoadFinish(bannerAd: SPBannerAd) {
self.requestStatAd(type: "start", errorMsg: nil)
self.delegate?.bannerAdManagerDidLoadFinish?(adManager: self)
}
///广
func bannerAdDidShow(bannerAd: SPBannerAd) {
self.delegate?.bannerAdManagerDidShow?(adManager: self)
}
///广
func bannerAdDidDismiss(bannerAd: SPBannerAd) {
self.requestStatAd(type: "close", errorMsg: nil)
self.delegate?.bannerAdManagerDidDismiss?(adManager: self)
}
func bannerAdDidClick(ad: any SPBannerAd) {
self.requestStatAd(type: "click", errorMsg: nil)
}
}
//MARK: -------------- --------------
extension SPBannerAdManager {
func requestStatAd(type: String, errorMsg: String?) {
guard self.view.superview != nil else { return }
let model = SPStatAdModel()
model.type = type
model.ads_id = adUnitID
model.ad_platform_key = SPAdPlatformKey(rawValue: bannerAd.adPlatformKey)
model.error_msg = errorMsg
model.scene = .banner
SPStatAPI.requestStatAd(model: model)
}
@objc private func didEnterBackgroundNotification() {
self.requestStatAd(type: "Interrupt", errorMsg: nil)
}
}

View File

@ -44,6 +44,9 @@ extension SPRewardedAdManager {
} }
} }
func admob_isReady() -> Bool {
return admob_rewardedAd != nil ? true : false
}
///广 ///广
func admob_loadAndShowRewardedAd(adInfo: SPAdInfo) { func admob_loadAndShowRewardedAd(adInfo: SPAdInfo) {
@ -75,7 +78,6 @@ extension SPRewardedAdManager {
let request = Request() let request = Request()
self.admob_isLoadingRewardedAd = true self.admob_isLoadingRewardedAd = true
spLog(message: "====Ad 加载广告")
RewardedAd.load(with: adUnitID, request: request) { [weak self] rewardedAd, error in RewardedAd.load(with: adUnitID, request: request) { [weak self] rewardedAd, error in
guard let self = self else { return } guard let self = self else { return }
self.admob_isLoadingRewardedAd = false self.admob_isLoadingRewardedAd = false
@ -83,7 +85,6 @@ extension SPRewardedAdManager {
if let error = error { if let error = error {
self.admob_needShowRewardedAd = false self.admob_needShowRewardedAd = false
self.loadFailHandler(error: error) self.loadFailHandler(error: error)
spLog(message: "====Ad 广告加载失败")
return return
} }
self.loadFinishHandler() self.loadFinishHandler()
@ -94,7 +95,6 @@ extension SPRewardedAdManager {
if self.admob_needShowRewardedAd { if self.admob_needShowRewardedAd {
self.admob_show() self.admob_show()
} }
spLog(message: "====Ad 广告加载成功")
} }
} }
@ -102,14 +102,12 @@ extension SPRewardedAdManager {
///广 ///广
private func admob_show() { private func admob_show() {
guard let rewardedAd = admob_rewardedAd, self.admob_needShowRewardedAd else { guard let rewardedAd = admob_rewardedAd, self.admob_needShowRewardedAd else {
return print("====Ad wasn't ready.") return
} }
self.admob_needShowRewardedAd = false self.admob_needShowRewardedAd = false
// The UIViewController parameter is an optional. // The UIViewController parameter is an optional.
rewardedAd.present(from: nil) { [weak self] in rewardedAd.present(from: nil) { [weak self] in
let reward = rewardedAd.adReward
print("Reward received with currency \(reward.amount), amount \(reward.amount.doubleValue)")
self?.userDidEarnRewardHandler() self?.userDidEarnRewardHandler()
// TODO: Reward the user. // TODO: Reward the user.
} }
@ -127,13 +125,11 @@ extension SPRewardedAdManager: FullScreenContentDelegate {
/// Tells the delegate that the ad will present full screen content. /// Tells the delegate that the ad will present full screen content.
func adWillPresentFullScreenContent(_ ad: FullScreenPresentingAd) { func adWillPresentFullScreenContent(_ ad: FullScreenPresentingAd) {
print("====Ad will present full screen content.")
self.didShowHandler() self.didShowHandler()
} }
/// Tells the delegate that the ad dismissed full screen content. /// Tells the delegate that the ad dismissed full screen content.
func adDidDismissFullScreenContent(_ ad: FullScreenPresentingAd) { func adDidDismissFullScreenContent(_ ad: FullScreenPresentingAd) {
print("====Ad did dismiss full screen content.")
self.admob_rewardedAd = nil self.admob_rewardedAd = nil
self.didDismissHandler() self.didDismissHandler()

View File

@ -61,13 +61,13 @@ extension SPRewardedAdManager {
func appLovin_loadRewardedAd(adInfo: SPAdInfo) { func appLovin_loadRewardedAd(adInfo: SPAdInfo) {
#if canImport(AppLovinSDK) #if canImport(AppLovinSDK)
if !appLovin_isLoadingRewardedAd { if self.appLovin_isLoadingRewardedAd { return }
self.appLovin_isLoadingRewardedAd = true self.appLovin_isLoadingRewardedAd = true
appLovin_rewardedAd = MARewardedAd.shared(withAdUnitIdentifier: adInfo.ads_id ?? "")
appLovin_rewardedAd?.delegate = self self.appLovin_rewardedAd = MARewardedAd.shared(withAdUnitIdentifier: adInfo.ads_id ?? "")
appLovin_rewardedAd?.load() self.appLovin_rewardedAd?.delegate = self
} self.appLovin_rewardedAd?.load()
#endif #endif
} }

View File

@ -62,7 +62,7 @@ class SPRewardedAdManager: NSObject {
func isAdAvailable() -> Bool { func isAdAvailable() -> Bool {
guard let adInfo = adInfo else { return false } guard let adInfo = adInfo else { return false }
if adInfo.platform_key == .google { if adInfo.platform_key == .google {
return admob_rewardedAd != nil ? true : false return admob_isReady()
} else if adInfo.platform_key == .applovin { } else if adInfo.platform_key == .applovin {
return appLovin_isReady() return appLovin_isReady()
} }
@ -90,60 +90,43 @@ class SPRewardedAdManager: NSObject {
SPHUD.show() SPHUD.show()
} }
if let adInfo = adInfo {//广
if adInfo.platform_key == .google {
self.admob_loadAndShowRewardedAd(adInfo: adInfo)
} else if adInfo.platform_key == .applovin {
self.appLovin_loadAndShowRewardedAd(adInfo: adInfo)
}
} else {
guard !isLoadingRewardedAd else { return } guard !isLoadingRewardedAd else { return }
if !isAdAvailable() {
self.isLoadingRewardedAd = true self.isLoadingRewardedAd = true
SPAdAPI.requestShowAdInfo { [weak self] adInfo in
guard let self = self else { return }
guard let adInfo = adInfo else {
let text = "movia_no_ads_tip".localized
let error = NSError(domain: text.localized, code: -1)
loadFailHandler(isStat: false, error: error)
return
} }
self.adInfo = adInfo
self.requestAdInfo { [weak self] adInfo in
guard let self = self else { return }
if adInfo.platform_key == .google { if adInfo.platform_key == .google {
self.admob_loadAndShowRewardedAd(adInfo: adInfo) self.admob_loadAndShowRewardedAd(adInfo: adInfo)
} else if adInfo.platform_key == .applovin { } else if adInfo.platform_key == .applovin {
self.appLovin_loadAndShowRewardedAd(adInfo: adInfo) self.appLovin_loadAndShowRewardedAd(adInfo: adInfo)
} else { } else {
self.isLoadingRewardedAd = false
self.adInfo = nil self.adInfo = nil
} }
} }
} }
}
///广 ///广
func preloadRewardedAd() { func preloadRewardedAd() {
guard isEnable else { return } guard isEnable else { return }
guard !isLoadingRewardedAd else { return } guard !isLoadingRewardedAd else { return }
guard self.adInfo == nil else { return }
isShowLoading = false isShowLoading = false
isShowToast = false isShowToast = false
self.isLoadingRewardedAd = true self.isLoadingRewardedAd = true
SPAdAPI.requestShowAdInfo { [weak self] adInfo in self.requestAdInfo { [weak self] adInfo in
guard let self = self else { return } guard let self = self else { return }
guard let adInfo = adInfo else {
self.isLoadingRewardedAd = false
return
}
self.adInfo = adInfo
if adInfo.platform_key == .google { if adInfo.platform_key == .google {
self.admob_loadRewardedAd(adInfo: adInfo) self.admob_loadRewardedAd(adInfo: adInfo)
} else if adInfo.platform_key == .applovin { } else if adInfo.platform_key == .applovin {
self.appLovin_loadRewardedAd(adInfo: adInfo) self.appLovin_loadRewardedAd(adInfo: adInfo)
} else { } else {
self.isLoadingRewardedAd = false
self.adInfo = nil self.adInfo = nil
} }
} }
@ -169,7 +152,6 @@ class SPRewardedAdManager: NSObject {
} }
private func clean() { private func clean() {
self.adInfo = nil
self.statScene = nil self.statScene = nil
self.videoInfo = nil self.videoInfo = nil
} }
@ -256,6 +238,7 @@ extension SPRewardedAdManager {
} }
///广 ///广
func didDismissHandler() { func didDismissHandler() {
let adInfo = self.adInfo
var seconds = 0 var seconds = 0
if let adsDate = self.adsDate { if let adsDate = self.adsDate {
@ -264,13 +247,13 @@ extension SPRewardedAdManager {
self.requestStatAd(type: "close", seconds: seconds, errorMsg: nil) { [weak self] in self.requestStatAd(type: "close", seconds: seconds, errorMsg: nil) { [weak self] in
guard let self = self else { return } guard let self = self else { return }
if let adInfo = self.adInfo { if let adInfo = adInfo {
self.delegate?.rewardedAdManager?(manager: self, didDismiss: adInfo) self.delegate?.rewardedAdManager?(manager: self, didDismiss: adInfo)
} }
}
self.clean() self.clean()
self.preloadRewardedAd() self.preloadRewardedAd()
}
} }
@ -314,4 +297,25 @@ extension SPRewardedAdManager {
func showToast(text: String? = "movia_no_ads_tip".localized) { func showToast(text: String? = "movia_no_ads_tip".localized) {
SPToast.show(text: text) 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!)
}
}
} }

View File

@ -17,30 +17,42 @@ class SPAdManager: NSObject {
static let manager = SPAdManager() static let manager = SPAdManager()
/// AppLovinSDK
private var appLovininitializeCompleter: (() -> Void)?
func start() { func start() {
//admob //admob
MobileAds.shared.start() MobileAds.shared.start()
initialize_applovinSdk(completer: nil)
}
///AppLovinSDK
func initialize_applovinSdk(completer: (() -> Void)? = nil) {
if completer != nil {
self.appLovininitializeCompleter = completer
}
#if canImport(AppLovinSDK) #if canImport(AppLovinSDK)
if !ALSdk.shared().isInitialized {
// //
let initConfig = ALSdkInitializationConfiguration(sdkKey: "XW2aulJv9urKD4MIIFT1xcSCuyTHaDZ9qUbDqygnTLS04GkdX7WMQJviGP5vDRWGsk4OJJIyLGRV3mbLqOWx0W") { builder in let initConfig = ALSdkInitializationConfiguration(sdkKey: "XW2aulJv9urKD4MIIFT1xcSCuyTHaDZ9qUbDqygnTLS04GkdX7WMQJviGP5vDRWGsk4OJJIyLGRV3mbLqOWx0W") { builder in
builder.mediationProvider = ALMediationProviderMAX builder.mediationProvider = ALMediationProviderMAX
#if DEBUG //#if DEBUG
builder.testDeviceAdvertisingIdentifiers = [JXUUID.idfa()] // builder.testDeviceAdvertisingIdentifiers = [JXUUID.idfa()]
#endif //#endif
} }
// Initialize the SDK with the configuration
ALSdk.shared().initialize(with: initConfig) { sdkConfig in ALSdk.shared().initialize(with: initConfig) { sdkConfig in
// Start loading ads // Start loading ads
self.appLovininitializeCompleter?()
}
} else {
self.appLovininitializeCompleter?()
} }
#endif #endif
} }
} }
//MARK: -------------- ID -------------- //MARK: -------------- ID --------------
@ -48,31 +60,38 @@ extension SPAdManager {
///广ID ///广ID
var admob_rewardedAdUnitID: String { var admob_rewardedAdUnitID: String {
#if DEBUG //#if DEBUG
return "ca-app-pub-3940256099942544/1712485313" // return "ca-app-pub-3940256099942544/1712485313"
#else //#else
return "" //#endif
#endif return "ca-app-pub-5209443898911659/3535954087"
} }
///广ID ///广ID
var appOpenAdUnitID: String { var admob_appOpenAdUnitID: String {
#if DEBUG //#if DEBUG
return "ca-app-pub-3940256099942544/5575463023" // return "ca-app-pub-3940256099942544/5575463023"
#else //#else
return "" //#endif
#endif return "ca-app-pub-5209443898911659/3886651330"
} }
///广ID ///广ID
var bannerAdUnitID: String { var admob_bannerAdUnitID: String {
#if DEBUG //#if DEBUG
return "ca-app-pub-3940256099942544/2435281174" // return "ca-app-pub-3940256099942544/2435281174"
#else //#else
//#endif
return "ca-app-pub-5209443898911659/8858726666"
}
///广ID
var applovin_appOpenAdUnitID: String {
return ""
}
///广ID
var applovin_bannerAdUnitID: String {
return "" return ""
#endif
} }
} }

View File

@ -30,7 +30,7 @@
<key>FirebaseAppDelegateProxyEnabled</key> <key>FirebaseAppDelegateProxyEnabled</key>
<false/> <false/>
<key>GADApplicationIdentifier</key> <key>GADApplicationIdentifier</key>
<string>ca-app-pub-3940256099942544~1458002511</string> <string>ca-app-pub-5209443898911659~1849745003</string>
<key>LSApplicationQueriesSchemes</key> <key>LSApplicationQueriesSchemes</key>
<array> <array>
<string>fbapi</string> <string>fbapi</string>