Commit 0347577b8310189f84eb0ce6a5e078cb79b786c9

Authored by “张旭”
1 parent 85e6297c

1.1.6.25.04.24.19 ,,提审

metaCode.xcodeproj/project.pbxproj
@@ -201,7 +201,6 @@ @@ -201,7 +201,6 @@
201 196A55F92D963AE700B06DB7 /* CNLiveVodLandscapeGaoqingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196A55F82D963AE600B06DB7 /* CNLiveVodLandscapeGaoqingView.swift */; }; 201 196A55F92D963AE700B06DB7 /* CNLiveVodLandscapeGaoqingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196A55F82D963AE600B06DB7 /* CNLiveVodLandscapeGaoqingView.swift */; };
202 196A55FB2D9BE7DC00B06DB7 /* CNLiveVodPayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196A55FA2D9BE7DC00B06DB7 /* CNLiveVodPayView.swift */; }; 202 196A55FB2D9BE7DC00B06DB7 /* CNLiveVodPayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196A55FA2D9BE7DC00B06DB7 /* CNLiveVodPayView.swift */; };
203 196A55FD2DA66AEE00B06DB7 /* CNLiveVodXuanjiKandianCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196A55FC2DA66AED00B06DB7 /* CNLiveVodXuanjiKandianCell.swift */; }; 203 196A55FD2DA66AEE00B06DB7 /* CNLiveVodXuanjiKandianCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196A55FC2DA66AED00B06DB7 /* CNLiveVodXuanjiKandianCell.swift */; };
204 - 196A55FF2DB766BC00B06DB7 /* LaunchAdManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196A55FE2DB766BC00B06DB7 /* LaunchAdManager.swift */; };  
205 196A56012DB7717B00B06DB7 /* CNOSAdImgDownloadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196A56002DB7717B00B06DB7 /* CNOSAdImgDownloadManager.swift */; }; 204 196A56012DB7717B00B06DB7 /* CNOSAdImgDownloadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196A56002DB7717B00B06DB7 /* CNOSAdImgDownloadManager.swift */; };
206 196A56032DB7720A00B06DB7 /* CNLiveLaunchAdController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196A56022DB7720A00B06DB7 /* CNLiveLaunchAdController.swift */; }; 205 196A56032DB7720A00B06DB7 /* CNLiveLaunchAdController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196A56022DB7720A00B06DB7 /* CNLiveLaunchAdController.swift */; };
207 196A56062DB7752900B06DB7 /* CNLiveAdViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196A56052DB7752900B06DB7 /* CNLiveAdViewModel.swift */; }; 206 196A56062DB7752900B06DB7 /* CNLiveAdViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196A56052DB7752900B06DB7 /* CNLiveAdViewModel.swift */; };
@@ -609,7 +608,6 @@ @@ -609,7 +608,6 @@
609 196A55F82D963AE600B06DB7 /* CNLiveVodLandscapeGaoqingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNLiveVodLandscapeGaoqingView.swift; sourceTree = "<group>"; }; 608 196A55F82D963AE600B06DB7 /* CNLiveVodLandscapeGaoqingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNLiveVodLandscapeGaoqingView.swift; sourceTree = "<group>"; };
610 196A55FA2D9BE7DC00B06DB7 /* CNLiveVodPayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNLiveVodPayView.swift; sourceTree = "<group>"; }; 609 196A55FA2D9BE7DC00B06DB7 /* CNLiveVodPayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNLiveVodPayView.swift; sourceTree = "<group>"; };
611 196A55FC2DA66AED00B06DB7 /* CNLiveVodXuanjiKandianCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNLiveVodXuanjiKandianCell.swift; sourceTree = "<group>"; }; 610 196A55FC2DA66AED00B06DB7 /* CNLiveVodXuanjiKandianCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNLiveVodXuanjiKandianCell.swift; sourceTree = "<group>"; };
612 - 196A55FE2DB766BC00B06DB7 /* LaunchAdManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchAdManager.swift; sourceTree = "<group>"; };  
613 196A56002DB7717B00B06DB7 /* CNOSAdImgDownloadManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNOSAdImgDownloadManager.swift; sourceTree = "<group>"; }; 611 196A56002DB7717B00B06DB7 /* CNOSAdImgDownloadManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNOSAdImgDownloadManager.swift; sourceTree = "<group>"; };
614 196A56022DB7720A00B06DB7 /* CNLiveLaunchAdController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNLiveLaunchAdController.swift; sourceTree = "<group>"; }; 612 196A56022DB7720A00B06DB7 /* CNLiveLaunchAdController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNLiveLaunchAdController.swift; sourceTree = "<group>"; };
615 196A56052DB7752900B06DB7 /* CNLiveAdViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNLiveAdViewModel.swift; sourceTree = "<group>"; }; 613 196A56052DB7752900B06DB7 /* CNLiveAdViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CNLiveAdViewModel.swift; sourceTree = "<group>"; };
@@ -1511,7 +1509,6 @@ @@ -1511,7 +1509,6 @@
1511 196A56042DB7720F00B06DB7 /* AD */ = { 1509 196A56042DB7720F00B06DB7 /* AD */ = {
1512 isa = PBXGroup; 1510 isa = PBXGroup;
1513 children = ( 1511 children = (
1514 - 196A55FE2DB766BC00B06DB7 /* LaunchAdManager.swift */,  
1515 196A56002DB7717B00B06DB7 /* CNOSAdImgDownloadManager.swift */, 1512 196A56002DB7717B00B06DB7 /* CNOSAdImgDownloadManager.swift */,
1516 196A56022DB7720A00B06DB7 /* CNLiveLaunchAdController.swift */, 1513 196A56022DB7720A00B06DB7 /* CNLiveLaunchAdController.swift */,
1517 196A56052DB7752900B06DB7 /* CNLiveAdViewModel.swift */, 1514 196A56052DB7752900B06DB7 /* CNLiveAdViewModel.swift */,
@@ -2453,7 +2450,6 @@ @@ -2453,7 +2450,6 @@
2453 790D01A52A2DF65E00C5978D /* CNLiveLoginPickerView.swift in Sources */, 2450 790D01A52A2DF65E00C5978D /* CNLiveLoginPickerView.swift in Sources */,
2454 191733042B0F216E007BCC04 /* NSDictionary+CNLiveExtensions.swift in Sources */, 2451 191733042B0F216E007BCC04 /* NSDictionary+CNLiveExtensions.swift in Sources */,
2455 192ED48A2C5771930057244C /* CNLiveVitaeAddWorkSecCell.swift in Sources */, 2452 192ED48A2C5771930057244C /* CNLiveVitaeAddWorkSecCell.swift in Sources */,
2456 - 196A55FF2DB766BC00B06DB7 /* LaunchAdManager.swift in Sources */,  
2457 79BA085D2AB18E8300D01875 /* CNLiveSaveAuthDB.swift in Sources */, 2453 79BA085D2AB18E8300D01875 /* CNLiveSaveAuthDB.swift in Sources */,
2458 79282A3C2A2EDC2500B5F8CF /* NSString+CNLiveExtensions.swift in Sources */, 2454 79282A3C2A2EDC2500B5F8CF /* NSString+CNLiveExtensions.swift in Sources */,
2459 19D2CE632AE8B65D00691757 /* CNLiveDownSlideTool.swift in Sources */, 2455 19D2CE632AE8B65D00691757 /* CNLiveDownSlideTool.swift in Sources */,
@@ -2960,7 +2956,7 @@ @@ -2960,7 +2956,7 @@
2960 CODE_SIGN_ENTITLEMENTS = metaCode/metaCode.entitlements; 2956 CODE_SIGN_ENTITLEMENTS = metaCode/metaCode.entitlements;
2961 CODE_SIGN_IDENTITY = "Apple Development"; 2957 CODE_SIGN_IDENTITY = "Apple Development";
2962 CODE_SIGN_STYLE = Automatic; 2958 CODE_SIGN_STYLE = Automatic;
2963 - CURRENT_PROJECT_VERSION = 1.1.5.25.04.21.16; 2959 + CURRENT_PROJECT_VERSION = 1.1.6.25.04.24.19;
2964 DEBUG_INFORMATION_FORMAT = dwarf; 2960 DEBUG_INFORMATION_FORMAT = dwarf;
2965 DEVELOPMENT_TEAM = 94X49GG3ZW; 2961 DEVELOPMENT_TEAM = 94X49GG3ZW;
2966 ENABLE_BITCODE = NO; 2962 ENABLE_BITCODE = NO;
@@ -3033,7 +3029,7 @@ @@ -3033,7 +3029,7 @@
3033 "$(inherited)", 3029 "$(inherited)",
3034 "@executable_path/Frameworks", 3030 "@executable_path/Frameworks",
3035 ); 3031 );
3036 - MARKETING_VERSION = 1.1.5; 3032 + MARKETING_VERSION = 1.1.6;
3037 OTHER_LDFLAGS = ( 3033 OTHER_LDFLAGS = (
3038 "$(inherited)", 3034 "$(inherited)",
3039 "-all_load", 3035 "-all_load",
@@ -3216,7 +3212,7 @@ @@ -3216,7 +3212,7 @@
3216 CODE_SIGN_ENTITLEMENTS = metaCode/metaCode.entitlements; 3212 CODE_SIGN_ENTITLEMENTS = metaCode/metaCode.entitlements;
3217 CODE_SIGN_IDENTITY = "Apple Development"; 3213 CODE_SIGN_IDENTITY = "Apple Development";
3218 CODE_SIGN_STYLE = Automatic; 3214 CODE_SIGN_STYLE = Automatic;
3219 - CURRENT_PROJECT_VERSION = 1.1.5.25.04.21.16; 3215 + CURRENT_PROJECT_VERSION = 1.1.6.25.04.24.19;
3220 DEVELOPMENT_TEAM = 94X49GG3ZW; 3216 DEVELOPMENT_TEAM = 94X49GG3ZW;
3221 ENABLE_BITCODE = NO; 3217 ENABLE_BITCODE = NO;
3222 ENABLE_MODULE_VERIFIER = NO; 3218 ENABLE_MODULE_VERIFIER = NO;
@@ -3288,7 +3284,7 @@ @@ -3288,7 +3284,7 @@
3288 "$(inherited)", 3284 "$(inherited)",
3289 "@executable_path/Frameworks", 3285 "@executable_path/Frameworks",
3290 ); 3286 );
3291 - MARKETING_VERSION = 1.1.5; 3287 + MARKETING_VERSION = 1.1.6;
3292 OTHER_LDFLAGS = ( 3288 OTHER_LDFLAGS = (
3293 "$(inherited)", 3289 "$(inherited)",
3294 "-all_load", 3290 "-all_load",
metaCode/Classes/Other/AD/CNLiveLaunchAdController.swift
@@ -55,7 +55,7 @@ class CNLiveLaunchAdController:UIViewController,URLSessionTaskDelegate{ @@ -55,7 +55,7 @@ class CNLiveLaunchAdController:UIViewController,URLSessionTaskDelegate{
55 // 2. 存在有效URL时执行清理 55 // 2. 存在有效URL时执行清理
56 if !oldUrl.isEmpty { 56 if !oldUrl.isEmpty {
57 // 3. 检查图片缓存是否存在 57 // 3. 检查图片缓存是否存在
58 - if let cachedImage = CNOSAdImgDownloadManager.getOSImage(with: oldUrl) { 58 + if let cachedImageData = CNOSAdImgDownloadManager.getOSImage(with: oldUrl),let image = UIImage(data: cachedImageData) {
59 // 4. 异步执行资源清理(避免阻塞主线程) 59 // 4. 异步执行资源清理(避免阻塞主线程)
60 DispatchQueue.global(qos: .utility).async { 60 DispatchQueue.global(qos: .utility).async {
61 CNOSAdImgDownloadManager.clearOSImage(with: oldUrl) 61 CNOSAdImgDownloadManager.clearOSImage(with: oldUrl)
@@ -93,7 +93,11 @@ class CNLiveLaunchAdController:UIViewController,URLSessionTaskDelegate{ @@ -93,7 +93,11 @@ class CNLiveLaunchAdController:UIViewController,URLSessionTaskDelegate{
93 let modifyStatus = adv["modifyStatus"] as? Int 93 let modifyStatus = adv["modifyStatus"] as? Int
94 let oldModifyStatus = UserDefaults.standard.integer(forKey: "wjjAdv_modifyStatus") 94 let oldModifyStatus = UserDefaults.standard.integer(forKey: "wjjAdv_modifyStatus")
95 let imageUrl = UserDefaults.standard.string(forKey: "wjjAdv_imageUrl") 95 let imageUrl = UserDefaults.standard.string(forKey: "wjjAdv_imageUrl")
96 - let localImage = CNOSAdImgDownloadManager.getOSImage(with: imageUrl) 96 +// let localImage = CNOSAdImgDownloadManager.getOSImage(with: imageUrl)
  97 + var localImage:UIImage?
  98 + if let cachedImageData = CNOSAdImgDownloadManager.getOSImage(with: imageUrl),let localImg = UIImage(data: cachedImageData){
  99 + localImage = localImg
  100 + }
97 101
98 if (modifyStatus==oldModifyStatus && (modifyStatus != 0) && ((imageUrl?.count ?? 0 == 0) || (localImage != nil))) { 102 if (modifyStatus==oldModifyStatus && (modifyStatus != 0) && ((imageUrl?.count ?? 0 == 0) || (localImage != nil))) {
99 print("无变化") 103 print("无变化")
@@ -112,7 +116,7 @@ class CNLiveLaunchAdController:UIViewController,URLSessionTaskDelegate{ @@ -112,7 +116,7 @@ class CNLiveLaunchAdController:UIViewController,URLSessionTaskDelegate{
112 advImgUrl = advImgUrl?.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) 116 advImgUrl = advImgUrl?.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
113 117
114 if advImgUrl?.count ?? 0 > 0{ 118 if advImgUrl?.count ?? 0 > 0{
115 - if let newImage = CNOSAdImgDownloadManager.getOSImage(with: advImgUrl!) { 119 + if let newImage = CNOSAdImgDownloadManager.getOSImage(with: advImgUrl!) {
116 UserDefaults.standard.set(adv["duration"] as? Int ?? 0, forKey: "wjjAdv_duration")//时长 120 UserDefaults.standard.set(adv["duration"] as? Int ?? 0, forKey: "wjjAdv_duration")//时长
117 UserDefaults.standard.set(adv["wjjAdv"] as? Bool ?? false, forKey: "wjjAdv_isOpenExternal")//是否外部 121 UserDefaults.standard.set(adv["wjjAdv"] as? Bool ?? false, forKey: "wjjAdv_isOpenExternal")//是否外部
118 let linkUrl = adv["url"] as? String ?? "" 122 let linkUrl = adv["url"] as? String ?? ""
@@ -152,14 +156,26 @@ class CNLiveLaunchAdController:UIViewController,URLSessionTaskDelegate{ @@ -152,14 +156,26 @@ class CNLiveLaunchAdController:UIViewController,URLSessionTaskDelegate{
152 } 156 }
153 157
154 // 判断本地是否存在广告图片 158 // 判断本地是否存在广告图片
155 - if let newImage = CNOSAdImgDownloadManager.getOSImage(with: UserDefaults.standard.string(forKey: "wjjAdv_imageUrl")){ 159 + if let data = CNOSAdImgDownloadManager.getOSImage(with: UserDefaults.standard.string(forKey: "wjjAdv_imageUrl")), let newImage = YYImage(data: data){
  160 + let g = YYAnimatedImageView(image: newImage)
  161 + print("YYImage:\(g.image)")
  162 + let f = YYImage.animatedImage(withAnimatedGIFData: data)
  163 + let b = YYImage.gif(data: data)
  164 + let c = UIImage.sd_image(withGIFData: data)
  165 + let a = UIImage(data: data)
  166 + let d = YYFrameImage(data: data)
  167 + let e = YYImage(smallGIFData: data, scale: 1)
  168 +// let newImage = CNOSAdImgDownloadManager.getOSImage(with: UserDefaults.standard.string(forKey: "wjjAdv_imageUrl")){
156 // 显示广告 169 // 显示广告
157 // let yyImage = newImage as? YYImage 170 // let yyImage = newImage as? YYImage
158 - 171 + print("YYImage:\(newImage),UIImage:\(c)")
159 bgView.isUserInteractionEnabled = true 172 bgView.isUserInteractionEnabled = true
160 bgView.addSubview(advImg) 173 bgView.addSubview(advImg)
161 bgView.addSubview(skipBtn) 174 bgView.addSubview(skipBtn)
162 - bgView.image = newImage//yyImage 175 +// let gif = YYImage(named: "123.gif")
  176 + bgView.image = newImage//g.image//e//c//gif//newImage//yyImage
  177 + bgView.autoPlayAnimatedImage = true
  178 + bgView.startAnimating()
163 let duration = UserDefaults.standard.integer(forKey: "wjjAdv_duration") 179 let duration = UserDefaults.standard.integer(forKey: "wjjAdv_duration")
164 if duration > 0 { 180 if duration > 0 {
165 var second = duration > 1000 ? duration / 1000 : duration 181 var second = duration > 1000 ? duration / 1000 : duration
metaCode/Classes/Other/AD/CNOSAdImgDownloadManager.swift
@@ -34,27 +34,36 @@ final class CNOSAdImgDownloadManager { @@ -34,27 +34,36 @@ final class CNOSAdImgDownloadManager {
34 34
35 let ocUrl: NSString = NSString(string: url ?? "") 35 let ocUrl: NSString = NSString(string: url ?? "")
36 if let md5Key = ocUrl.md5(){ 36 if let md5Key = ocUrl.md5(){
37 - shared.cache.store(image, forKey: md5Key, completion: {  
38 - success?()  
39 - }) 37 + guard let data = image.imageData else { return }//image.sd_imageData()
  38 + shared.cache.storeImageData(toDisk: data, forKey: md5Key)
  39 +// shared.cache.store(image, forKey: md5Key, completion: {
  40 +// success?()
  41 +// })
40 } 42 }
41 } 43 }
42 } 44 }
43 45
44 /// 获取缓存图片 46 /// 获取缓存图片
45 - static func getOSImage(with url: String?) -> UIImage? { 47 + static func getOSImage(with url: String?) -> Data? {
46 let ocUrl: NSString = NSString(string: url ?? "") 48 let ocUrl: NSString = NSString(string: url ?? "")
47 if let md5Key = ocUrl.md5(){ 49 if let md5Key = ocUrl.md5(){
48 - return shared.cache.imageFromCache(forKey: md5Key)// as? YYImage 50 + let isCached = shared.cache.diskImageDataExists(withKey: md5Key)
  51 +
  52 + if isCached{
  53 + return shared.cache.diskImageData(forKey: md5Key)
  54 + }
  55 +
  56 +// return shared.cache.imageFromCache(forKey: md5Key)// as? YYImage
49 } 57 }
50 - return shared.cache.imageFromCache(forKey: "")// as? YYImage 58 + return nil//shared.cache.imageFromCache(forKey: "")// as? YYImage
51 } 59 }
52 60
53 /// 清除指定图片缓存 61 /// 清除指定图片缓存
54 static func clearOSImage(with url: String?) { 62 static func clearOSImage(with url: String?) {
55 let ocUrl: NSString = NSString(string: url ?? "") 63 let ocUrl: NSString = NSString(string: url ?? "")
56 if let md5Key = ocUrl.md5(){ 64 if let md5Key = ocUrl.md5(){
57 - shared.cache.removeImage(forKey: md5Key, withCompletion: nil) 65 + shared.cache.removeImageFromDisk(forKey: md5Key)
  66 +// shared.cache.removeImage(forKey: md5Key, withCompletion: nil)
58 } 67 }
59 } 68 }
60 } 69 }
metaCode/Classes/Other/AD/LaunchAdManager.swift deleted 100644 → 0
1 -//  
2 -// LaunchAdManager.swift  
3 -// metaCode  
4 -//  
5 -// Created by zx on 2025/4/22.  
6 -//  
7 -  
8 -import Foundation  
9 -import UIKit  
10 -  
11 -final class LaunchAdManager {  
12 - static let shared = LaunchAdManager()  
13 - private var adViewController: LaunchAdViewController?  
14 - private var adDataTask: URLSessionDataTask?  
15 -  
16 - /// 预加载广告资源 :ml-citation{ref="1,3" data="citationList"}  
17 - func loadAd() {  
18 - let adURL = URL(string: "https://wjj.ys2.cnliveimg.com/769/img/2/2025/01/22/173751152842250414939.jpg")!  
19 -  
20 - adDataTask?.cancel()  
21 - adDataTask = URLSession.shared.dataTask(with: adURL) { [weak self] data, _, _ in  
22 - guard let data = data else { return }  
23 - DispatchQueue.main.async {  
24 - self?.cacheAdImage(UIImage(data: data))  
25 - }  
26 - }  
27 - adDataTask?.resume()  
28 - }  
29 -  
30 - /// 显示广告页(在AppDelegate中调用)  
31 - func showAdIfNeeded(in window: UIWindow?) {  
32 -// guard !UserSessionManager.shared.isLoggedIn() else {  
33 -// window?.switchToMainUI()  
34 -// return  
35 -// }  
36 -  
37 - adViewController = LaunchAdViewController()  
38 - window?.rootViewController = adViewController  
39 - window?.makeKeyAndVisible()  
40 - }  
41 -  
42 - private func cacheAdImage(_ image: UIImage?) {  
43 - // 实现广告图片缓存逻辑(可扩展为文件存储)  
44 - UserDefaults.standard.set(image?.pngData(), forKey: "cachedAdImage")  
45 - }  
46 -}  
47 -  
48 -// MARK: - 广告页控制器实现  
49 -private class LaunchAdViewController: UIViewController {  
50 - private let countdownSeconds = 5  
51 - private var remainingSeconds = 5  
52 - private var timer: Timer?  
53 -  
54 - override func viewDidLoad() {  
55 - super.viewDidLoad()  
56 - setupUI()  
57 - startCountdown()  
58 - loadCachedAd()  
59 - }  
60 -  
61 - private func setupUI() {  
62 - view.backgroundColor = .white  
63 - let skipButton = UIButton(type: .system)  
64 - skipButton.setTitle("跳过 \(countdownSeconds)s", for: .normal)  
65 - skipButton.addTarget(self, action: #selector(skipAd), for: .touchUpInside)  
66 - // 布局代码略...  
67 - }  
68 -  
69 - @objc private func skipAd() {  
70 - timer?.invalidate()  
71 - switchToMainUI()  
72 - }  
73 -  
74 - private func startCountdown() {  
75 - timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in  
76 - guard let self = self else { return }  
77 - self.remainingSeconds -= 1  
78 - if self.remainingSeconds <= 0 {  
79 - self.switchToMainUI()  
80 - }  
81 - }  
82 - }  
83 -  
84 - private func loadCachedAd() {  
85 - if let data = UserDefaults.standard.data(forKey: "cachedAdImage") {  
86 - let imageView = UIImageView(image: UIImage(data: data))  
87 - imageView.contentMode = .scaleAspectFill  
88 - view.addSubview(imageView)  
89 - // 布局代码略...  
90 - }  
91 - }  
92 -  
93 - fileprivate func switchToMainUI() {  
94 - UIView.transition(with: view.window!,  
95 - duration: 0.3,  
96 - options: .transitionCrossDissolve,  
97 - animations: {  
98 - self.view.window?.switchToMainUI()  
99 - })  
100 - }  
101 -}  
102 -  
103 -// MARK: - 登录状态管理(UserDefaults方案)  
104 -final class UserSessionManager {  
105 - static let shared = UserSessionManager()  
106 - private init() {}  
107 -  
108 - func isLoggedIn() -> Bool {  
109 - return UserDefaults.standard.bool(forKey: "isLoggedIn")  
110 - }  
111 -}  
112 -  
113 -// MARK: - 窗口切换扩展  
114 -extension UIWindow {  
115 - func switchToMainUI() {  
116 - rootViewController = CNLiveBaseTabBarViewController.init()  
117 - makeKeyAndVisible()  
118 - }  
119 -}