看广告签到
This commit is contained in:
parent
1771235bec
commit
0232c818d8
@ -280,6 +280,7 @@
|
||||
1BF5130C2E1F4660009750EA /* SPRewardedAdManager+AppLovin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF5130B2E1F4654009750EA /* SPRewardedAdManager+AppLovin.swift */; };
|
||||
1BF5130E2E1F5D9B009750EA /* SPRewardedAdManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF5130D2E1F5D8F009750EA /* SPRewardedAdManager.swift */; };
|
||||
1BF513112E1FA138009750EA /* SPStatAdModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF513102E1FA138009750EA /* SPStatAdModel.swift */; };
|
||||
1BF513142E1FB8C1009750EA /* SPAppOpenAdManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BF513132E1FB8C1009750EA /* SPAppOpenAdManager.swift */; };
|
||||
C3D1CE788CA03A1878493356 /* Pods_ThimraTV.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B64805795B479324EB764157 /* Pods_ThimraTV.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@ -591,6 +592,7 @@
|
||||
1BF5130B2E1F4654009750EA /* SPRewardedAdManager+AppLovin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SPRewardedAdManager+AppLovin.swift"; sourceTree = "<group>"; };
|
||||
1BF5130D2E1F5D8F009750EA /* SPRewardedAdManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPRewardedAdManager.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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@ -1480,6 +1482,7 @@
|
||||
1BDE20112E1E158400C2C2B5 /* AdManager */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1BF513122E1FB897009750EA /* AppOpenAd */,
|
||||
1BF5130F2E1F5EE4009750EA /* RewardedAd */,
|
||||
1BDE20122E1E159B00C2C2B5 /* SPAdManager.swift */,
|
||||
1BDE20182E1E175800C2C2B5 /* SPAdInfo.swift */,
|
||||
@ -1498,6 +1501,14 @@
|
||||
path = RewardedAd;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1BF513122E1FB897009750EA /* AppOpenAd */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1BF513132E1FB8C1009750EA /* SPAppOpenAdManager.swift */,
|
||||
);
|
||||
path = AppOpenAd;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1DBC40502DA4EDFC0093FCB0 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1773,6 +1784,7 @@
|
||||
1BB91D492E04FD6A00A2C715 /* SPTextField.swift in Sources */,
|
||||
1BB91D4A2E04FD6A00A2C715 /* SPCampaignWebViewController.swift in Sources */,
|
||||
1BB91D4B2E04FD6A00A2C715 /* SPWebMessageModel.swift in Sources */,
|
||||
1BF513142E1FB8C1009750EA /* SPAppOpenAdManager.swift in Sources */,
|
||||
1BDE20192E1E175800C2C2B5 /* SPAdInfo.swift in Sources */,
|
||||
1BB91D4C2E04FD6A00A2C715 /* SPWebView.swift in Sources */,
|
||||
1BB91D4D2E04FD6A00A2C715 /* SPWebViewController.swift in Sources */,
|
||||
@ -2094,7 +2106,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.1.2;
|
||||
MARKETING_VERSION = 1.1.3;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.thimratv.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@ -2142,7 +2154,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.1.2;
|
||||
MARKETING_VERSION = 1.1.3;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.thimratv.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
@ -20,7 +20,7 @@ class SPTabBarController: UITabBarController {
|
||||
|
||||
let nav3 = createNavigationController(viewController: SPMyListViewController(), title: "movia_my_list".localized, image: UIImage(named: "tabbar_icon_04"), selectedImage: UIImage(named: "tabbar_icon_04_selected"))
|
||||
|
||||
let nav4 = createNavigationController(viewController: SPRewardsViewController(), title: "movia_rewards".localized, image: UIImage(named: "tabbar_icon_04"), selectedImage: UIImage(named: "tabbar_icon_04_selected"))
|
||||
let nav4 = createNavigationController(viewController: SPRewardsViewController(), title: "movia_rewards".localized, image: UIImage(named: "tabbar_icon_03"), selectedImage: UIImage(named: "tabbar_icon_03_selected"))
|
||||
|
||||
let nav5 = createNavigationController(viewController: SPMineViewController(), title: "movia_profile".localized, image: UIImage(named: "tabbar_icon_05"), selectedImage: UIImage(named: "tabbar_icon_05_selected"))
|
||||
|
||||
|
@ -74,7 +74,7 @@ class SPStatAPI: NSObject {
|
||||
}
|
||||
|
||||
///广告统计
|
||||
static func requestStatAd(model: SPStatAdModel) {
|
||||
static func requestStatAd(model: SPStatAdModel, completer: (() -> Void)? = nil) {
|
||||
|
||||
var param = SPNetworkParameters(path: "/ad/history")
|
||||
param.isToast = false
|
||||
@ -82,7 +82,7 @@ class SPStatAPI: NSObject {
|
||||
param.parameters = model.toDictionary()
|
||||
|
||||
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<String>) in
|
||||
|
||||
completer?()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ class SPWebView: WKWebView {
|
||||
WebMessageOpenFeedbackList,
|
||||
WebMessageOpenFeedbackDetail,
|
||||
WebMessageOpenPhotoPicker,
|
||||
WebMessageOpenCheckSignIn,
|
||||
]
|
||||
|
||||
|
||||
@ -62,8 +63,8 @@ class SPWebView: WKWebView {
|
||||
|
||||
func load(urlStr: String) {
|
||||
guard let url = URL(string: urlStr) else { return }
|
||||
// var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 30)
|
||||
var request = URLRequest(url: url, cachePolicy: .returnCacheDataElseLoad, timeoutInterval: 30)
|
||||
// let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 30)
|
||||
let request = URLRequest(url: url, cachePolicy: .returnCacheDataElseLoad, timeoutInterval: 30)
|
||||
self.load(request)
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,8 @@ let WebMessageOpenFeedbackList: SPWebViewMessageName = "openFeedbackList"
|
||||
let WebMessageOpenFeedbackDetail: SPWebViewMessageName = "openFeedbackDetail"
|
||||
///打开相册
|
||||
let WebMessageOpenPhotoPicker: SPWebViewMessageName = "openPhotoPicker"
|
||||
///点击签到
|
||||
let WebMessageOpenCheckSignIn: SPWebViewMessageName = "openCheckSignIn"
|
||||
|
||||
|
||||
extension SPWebViewController {
|
||||
@ -74,7 +76,12 @@ extension SPWebViewController {
|
||||
|
||||
}
|
||||
|
||||
|
||||
} else if name == WebMessageOpenCheckSignIn { //点击点到
|
||||
self.needAutoRefresh = false
|
||||
let manager = SPRewardedAdManager.manager
|
||||
manager.statScene = .reward
|
||||
manager.delegate = self
|
||||
manager.loadAndShowRewardedAd()
|
||||
|
||||
}
|
||||
|
||||
@ -117,3 +124,22 @@ extension SPWebViewController: TZImagePickerControllerDelegate {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//MARK: -------------- SPRewardedAdManagerDelegate --------------
|
||||
extension SPWebViewController: SPRewardedAdManagerDelegate {
|
||||
|
||||
func rewardedAdManager(manager: SPRewardedAdManager, didLoadFail error: any Error) {
|
||||
self.needAutoRefresh = true
|
||||
}
|
||||
|
||||
func rewardedAdManager(manager: SPRewardedAdManager, didDisplayFail error: any Error) {
|
||||
self.needAutoRefresh = true
|
||||
}
|
||||
|
||||
func rewardedAdManagerDidDismiss(manager: SPRewardedAdManager) {
|
||||
self.needAutoRefresh = true
|
||||
|
||||
let js = "uploadCheckSignIn()"
|
||||
self.webView.evaluateJavaScript(js)
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ class SPWebViewController: SPViewController {
|
||||
///自动设置标题
|
||||
var autoTitle = true
|
||||
|
||||
var needAutoRefresh = true
|
||||
|
||||
private(set) lazy var webView: SPWebView = {
|
||||
let controller = WKUserContentController()
|
||||
|
||||
@ -51,10 +53,7 @@ class SPWebViewController: SPViewController {
|
||||
func load(urlString: String) {
|
||||
let str: String = urlString
|
||||
|
||||
guard let url = URL(string: str) else { return }
|
||||
let request = URLRequest(url: url, timeoutInterval: 30)
|
||||
|
||||
self.webView.load(request)
|
||||
self.webView.load(urlStr: str)
|
||||
}
|
||||
|
||||
func reload() {
|
||||
|
@ -118,6 +118,7 @@ extension SPMineViewController {
|
||||
guard SPLoginManager.manager.userInfo?.user_level == .ad else { return }
|
||||
guard needShowRewardedAd else { return }
|
||||
needShowRewardedAd = false
|
||||
guard SPRewardedAdManager.manager.isEnable else { return }
|
||||
|
||||
let manager = SPRewardedAdManager.manager
|
||||
manager.statScene = .me
|
||||
|
@ -16,6 +16,7 @@ class SPRewardsViewController: SPCampaignWebViewController {
|
||||
private var isFirst = true
|
||||
|
||||
|
||||
|
||||
override func viewDidLoad() {
|
||||
self.urlStr = SPRewardsWebUrl
|
||||
super.viewDidLoad()
|
||||
@ -54,7 +55,9 @@ class SPRewardsViewController: SPCampaignWebViewController {
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
if !isFirst {
|
||||
self.reload()
|
||||
if needAutoRefresh {
|
||||
self.reload()
|
||||
}
|
||||
} else {
|
||||
isFirst = false
|
||||
}
|
||||
|
83
ThimraTV/Libs/AdManager/AppOpenAd/SPAppOpenAdManager.swift
Normal file
83
ThimraTV/Libs/AdManager/AppOpenAd/SPAppOpenAdManager.swift
Normal file
@ -0,0 +1,83 @@
|
||||
//
|
||||
// SPAppOpenAdManager.swift
|
||||
// ThimraTV
|
||||
//
|
||||
// Created by 长沙佳儿 on 2025/7/10.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import GoogleMobileAds
|
||||
|
||||
class SPAppOpenAdManager: NSObject {
|
||||
|
||||
var appOpenAd: AppOpenAd?
|
||||
var isLoadingAd = false
|
||||
var isShowingAd = false
|
||||
|
||||
static let shared = SPAppOpenAdManager()
|
||||
|
||||
private func loadAd() async {
|
||||
// Do not load ad if there is an unused ad or one is already loading.
|
||||
if isLoadingAd || isAdAvailable() {
|
||||
return
|
||||
}
|
||||
isLoadingAd = true
|
||||
|
||||
do {
|
||||
appOpenAd = try await AppOpenAd.load(with: "ca-app-pub-3940256099942544/5575463023", request: Request())
|
||||
|
||||
appOpenAd?.fullScreenContentDelegate = self
|
||||
} catch {
|
||||
print("App open ad failed to load with error: \(error.localizedDescription)")
|
||||
}
|
||||
isLoadingAd = false
|
||||
}
|
||||
|
||||
func showAdIfAvailable() {
|
||||
// If the app open ad is already showing, do not show the ad again.
|
||||
guard !isShowingAd else { return }
|
||||
|
||||
// If the app open ad is not available yet but is supposed to show, load
|
||||
// a new ad.
|
||||
if !isAdAvailable() {
|
||||
Task {
|
||||
await loadAd()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if let ad = appOpenAd {
|
||||
isShowingAd = true
|
||||
ad.present(from: nil)
|
||||
}
|
||||
}
|
||||
|
||||
private func isAdAvailable() -> Bool {
|
||||
// Check if ad exists and can be shown.
|
||||
return appOpenAd != nil
|
||||
}
|
||||
}
|
||||
|
||||
extension SPAppOpenAdManager: FullScreenContentDelegate {
|
||||
func adWillPresentFullScreenContent(_ ad: FullScreenPresentingAd) {
|
||||
print("App open ad will be presented.")
|
||||
}
|
||||
|
||||
func adDidDismissFullScreenContent(_ ad: FullScreenPresentingAd) {
|
||||
appOpenAd = nil
|
||||
isShowingAd = false
|
||||
// Reload an ad.
|
||||
Task {
|
||||
await loadAd()
|
||||
}
|
||||
}
|
||||
|
||||
func ad(_ ad: FullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {
|
||||
appOpenAd = nil
|
||||
isShowingAd = false
|
||||
// Reload an ad.
|
||||
Task {
|
||||
await loadAd()
|
||||
}
|
||||
}
|
||||
}
|
@ -36,6 +36,8 @@ class SPRewardedAdManager: NSObject {
|
||||
private var retryCount = 0
|
||||
///最大重试次数
|
||||
private let retryMaxCount = 1
|
||||
///广告激活状态
|
||||
private(set) var isEnable = true
|
||||
|
||||
private(set) var adInfo: SPAdInfo?
|
||||
|
||||
@ -47,6 +49,7 @@ class SPRewardedAdManager: NSObject {
|
||||
var statScene: SPStatAdModel.AdScene?
|
||||
var videoInfo: SPVideoInfoModel?
|
||||
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
@ -57,23 +60,41 @@ class SPRewardedAdManager: NSObject {
|
||||
}
|
||||
|
||||
///加载并展示激励广告
|
||||
func loadAndShowRewardedAd() {
|
||||
isShowLoading = true
|
||||
isShowToast = true
|
||||
func loadAndShowRewardedAd(isShowLoading: Bool = true, isShowToast: Bool = true) {
|
||||
guard isEnable else {
|
||||
let text = "movia_no_ads_tip".localized
|
||||
if isShowToast {
|
||||
SPToast.show(text: text)
|
||||
}
|
||||
self.isShowToast = false
|
||||
self.isShowLoading = false
|
||||
let error = NSError(domain: text.localized, code: -1)
|
||||
loadFailHandler(isStat: false, error: error)
|
||||
return
|
||||
}
|
||||
|
||||
SPHUD.show()
|
||||
self.isShowLoading = isShowLoading
|
||||
self.isShowToast = isShowToast
|
||||
|
||||
if let adInfo = adInfo {//已有广告,并且加载完成
|
||||
if self.isShowLoading {
|
||||
SPHUD.show()
|
||||
}
|
||||
|
||||
if let adInfo = adInfo {//已有广告
|
||||
if adInfo.platform_key == .google {
|
||||
self.admob_loadAndShowRewardedAd(adInfo: adInfo)
|
||||
}
|
||||
|
||||
} else {
|
||||
guard !isLoadingRewardedAd else { return }
|
||||
self.isLoadingRewardedAd = true
|
||||
|
||||
SPAdAPI.requestShowAdInfo { [weak self] adInfo in
|
||||
guard let self = self else { return }
|
||||
guard let adInfo = adInfo else {
|
||||
SPHUD.dismiss()
|
||||
SPToast.show(text: "movia_no_ads_tip".localized)
|
||||
let text = "movia_no_ads_tip".localized
|
||||
let error = NSError(domain: text.localized, code: -1)
|
||||
loadFailHandler(isStat: false, error: error)
|
||||
return
|
||||
}
|
||||
self.adInfo = adInfo
|
||||
@ -89,6 +110,7 @@ class SPRewardedAdManager: NSObject {
|
||||
|
||||
///预加载一个广告
|
||||
func preloadRewardedAd() {
|
||||
guard isEnable else { return }
|
||||
guard !isLoadingRewardedAd else { return }
|
||||
isShowLoading = false
|
||||
isShowToast = false
|
||||
@ -112,6 +134,8 @@ class SPRewardedAdManager: NSObject {
|
||||
|
||||
///重试加载广告
|
||||
private func retryLoadAd() {
|
||||
guard isEnable else { return }
|
||||
|
||||
guard retryCount < retryMaxCount else {
|
||||
retryCount = 0
|
||||
retryAttempt = 0
|
||||
@ -141,7 +165,7 @@ extension SPRewardedAdManager {
|
||||
}
|
||||
|
||||
///广告加载失败
|
||||
func loadFailHandler(error: Error) {
|
||||
func loadFailHandler(isStat: Bool = true, error: Error) {
|
||||
|
||||
if isShowLoading {
|
||||
SPHUD.dismiss()
|
||||
@ -151,10 +175,13 @@ extension SPRewardedAdManager {
|
||||
}
|
||||
self.isLoadingRewardedAd = false
|
||||
self.delegate?.rewardedAdManager?(manager: self, didLoadFail: error)
|
||||
self.requestStatAd(type: "load_failed", errorMsg: error.localizedDescription)
|
||||
if isStat {
|
||||
self.requestStatAd(type: "load_failed", errorMsg: error.localizedDescription)
|
||||
}
|
||||
|
||||
self.statScene = nil
|
||||
self.videoInfo = nil
|
||||
self.isEnable = false
|
||||
self.retryLoadAd()
|
||||
|
||||
}
|
||||
@ -195,13 +222,16 @@ extension SPRewardedAdManager {
|
||||
}
|
||||
///广告被关闭
|
||||
func didDismissHandler() {
|
||||
self.delegate?.rewardedAdManagerDidDismiss?(manager: self)
|
||||
|
||||
var seconds = 0
|
||||
if let adsDate = self.adsDate {
|
||||
seconds = Int(Date().timeIntervalSince(adsDate))
|
||||
}
|
||||
self.requestStatAd(type: "close", seconds: seconds, errorMsg: nil)
|
||||
|
||||
self.requestStatAd(type: "close", seconds: seconds, errorMsg: nil) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.delegate?.rewardedAdManagerDidDismiss?(manager: self)
|
||||
}
|
||||
|
||||
self.statScene = nil
|
||||
self.videoInfo = nil
|
||||
@ -224,7 +254,7 @@ extension SPRewardedAdManager {
|
||||
//MARK: -------------- 统计 --------------
|
||||
extension SPRewardedAdManager {
|
||||
|
||||
private func requestStatAd(type: String, seconds: Int = 0, errorMsg: String?) {
|
||||
private func requestStatAd(type: String, seconds: Int = 0, errorMsg: String?, completer: (() -> Void)? = nil) {
|
||||
guard let adInfo = adInfo else { return }
|
||||
|
||||
let model = SPStatAdModel()
|
||||
@ -237,7 +267,7 @@ extension SPRewardedAdManager {
|
||||
model.short_play_id = self.videoInfo?.short_play_id
|
||||
model.short_play_video_id = self.videoInfo?.short_play_video_id
|
||||
|
||||
SPStatAPI.requestStatAd(model: model)
|
||||
SPStatAPI.requestStatAd(model: model, completer: completer)
|
||||
}
|
||||
|
||||
|
||||
|
@ -13,6 +13,7 @@ class SPStatAdModel: SPModel, SmartCodable {
|
||||
enum AdScene: String, SmartCaseDefaultable {
|
||||
case detail = "detail"
|
||||
case me = "me"
|
||||
case reward = "reward"
|
||||
}
|
||||
|
||||
var type: String? //start click error click show_failed load_failed Interrupt(退到后台) close
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 779 B After Width: | Height: | Size: 958 B |
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
@ -5,10 +5,12 @@
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Frame@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Frame@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
|
BIN
ThimraTV/Source/Assets.xcassets/TabBar/tabbar_icon_03_selected.imageset/Frame@2x.png
vendored
Normal file
BIN
ThimraTV/Source/Assets.xcassets/TabBar/tabbar_icon_03_selected.imageset/Frame@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
ThimraTV/Source/Assets.xcassets/TabBar/tabbar_icon_03_selected.imageset/Frame@3x.png
vendored
Normal file
BIN
ThimraTV/Source/Assets.xcassets/TabBar/tabbar_icon_03_selected.imageset/Frame@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
Loading…
x
Reference in New Issue
Block a user