diff --git a/Fableon.xcodeproj/project.pbxproj b/Fableon.xcodeproj/project.pbxproj index ce9c43d..3ced65b 100644 --- a/Fableon.xcodeproj/project.pbxproj +++ b/Fableon.xcodeproj/project.pbxproj @@ -41,6 +41,20 @@ 031FDEEC2EB35DF600F4CAC7 /* FACoinsPackAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEEB2EB35DF600F4CAC7 /* FACoinsPackAlert.swift */; }; 031FDEEE2EB3682000F4CAC7 /* FAVipRetainAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEED2EB3682000F4CAC7 /* FAVipRetainAlert.swift */; }; 035589332F161E6E00FAEF4A /* FAPayRetainAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035589322F161E6E00FAEF4A /* FAPayRetainAlert.swift */; }; + 035589362F2305D800FAEF4A /* FAAdManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035589352F2305D800FAEF4A /* FAAdManager.swift */; }; + 0355893A2F234B3E00FAEF4A /* FAOpenAdManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035589392F234B3E00FAEF4A /* FAOpenAdManager.swift */; }; + 0355893C2F234C8300FAEF4A /* FATradPlusOpenAd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0355893B2F234C8300FAEF4A /* FATradPlusOpenAd.swift */; }; + 0355893E2F2464C100FAEF4A /* FAOpenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0355893D2F2464C100FAEF4A /* FAOpenViewController.swift */; }; + 035589402F24924300FAEF4A /* FARewardedAdManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0355893F2F24924300FAEF4A /* FARewardedAdManager.swift */; }; + 035589422F24945600FAEF4A /* FATradPlusRewardedAd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035589412F24945600FAEF4A /* FATradPlusRewardedAd.swift */; }; + 035589452F249CF200FAEF4A /* FABannerAdManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035589442F249CF200FAEF4A /* FABannerAdManager.swift */; }; + 035589472F249D9D00FAEF4A /* FATradPlusBannerAd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035589462F249D9D00FAEF4A /* FATradPlusBannerAd.swift */; }; + 035589492F273C5100FAEF4A /* FATradPlusInterstitialAd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035589482F273C5100FAEF4A /* FATradPlusInterstitialAd.swift */; }; + 0355894B2F274A9400FAEF4A /* FARewardedAdInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0355894A2F274A9400FAEF4A /* FARewardedAdInfo.swift */; }; + 0355894D2F27530800FAEF4A /* FARewardedAdOverview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0355894C2F27530800FAEF4A /* FARewardedAdOverview.swift */; }; + 035589502F2AEF3700FAEF4A /* FANativeAdManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0355894F2F2AEF3700FAEF4A /* FANativeAdManager.swift */; }; + 035589542F2AF1CB00FAEF4A /* FATradPlusNativeAd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035589532F2AF1CB00FAEF4A /* FATradPlusNativeAd.swift */; }; + 035589582F2B353200FAEF4A /* FATradPlusNativeAdView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035589572F2B353200FAEF4A /* FATradPlusNativeAdView.swift */; }; 039CE6042EAA2621007B5EED /* AppDelegate+FAAdjust.swift in Sources */ = {isa = PBXBuildFile; fileRef = 039CE6032EAA2612007B5EED /* AppDelegate+FAAdjust.swift */; }; 039CE6092EAA2F71007B5EED /* FAAdjustStateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 039CE6082EAA2F62007B5EED /* FAAdjustStateManager.swift */; }; 039CE60B2EAA31CB007B5EED /* FAStatAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 039CE60A2EAA31CB007B5EED /* FAStatAPI.swift */; }; @@ -416,6 +430,20 @@ 031FDEEB2EB35DF600F4CAC7 /* FACoinsPackAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FACoinsPackAlert.swift; sourceTree = ""; }; 031FDEED2EB3682000F4CAC7 /* FAVipRetainAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAVipRetainAlert.swift; sourceTree = ""; }; 035589322F161E6E00FAEF4A /* FAPayRetainAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAPayRetainAlert.swift; sourceTree = ""; }; + 035589352F2305D800FAEF4A /* FAAdManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAAdManager.swift; sourceTree = ""; }; + 035589392F234B3E00FAEF4A /* FAOpenAdManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAOpenAdManager.swift; sourceTree = ""; }; + 0355893B2F234C8300FAEF4A /* FATradPlusOpenAd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FATradPlusOpenAd.swift; sourceTree = ""; }; + 0355893D2F2464C100FAEF4A /* FAOpenViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAOpenViewController.swift; sourceTree = ""; }; + 0355893F2F24924300FAEF4A /* FARewardedAdManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FARewardedAdManager.swift; sourceTree = ""; }; + 035589412F24945600FAEF4A /* FATradPlusRewardedAd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FATradPlusRewardedAd.swift; sourceTree = ""; }; + 035589442F249CF200FAEF4A /* FABannerAdManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FABannerAdManager.swift; sourceTree = ""; }; + 035589462F249D9D00FAEF4A /* FATradPlusBannerAd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FATradPlusBannerAd.swift; sourceTree = ""; }; + 035589482F273C5100FAEF4A /* FATradPlusInterstitialAd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FATradPlusInterstitialAd.swift; sourceTree = ""; }; + 0355894A2F274A9400FAEF4A /* FARewardedAdInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FARewardedAdInfo.swift; sourceTree = ""; }; + 0355894C2F27530800FAEF4A /* FARewardedAdOverview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FARewardedAdOverview.swift; sourceTree = ""; }; + 0355894F2F2AEF3700FAEF4A /* FANativeAdManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FANativeAdManager.swift; sourceTree = ""; }; + 035589532F2AF1CB00FAEF4A /* FATradPlusNativeAd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FATradPlusNativeAd.swift; sourceTree = ""; }; + 035589572F2B353200FAEF4A /* FATradPlusNativeAdView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FATradPlusNativeAdView.swift; sourceTree = ""; }; 039CE6032EAA2612007B5EED /* AppDelegate+FAAdjust.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+FAAdjust.swift"; sourceTree = ""; }; 039CE6082EAA2F62007B5EED /* FAAdjustStateManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAAdjustStateManager.swift; sourceTree = ""; }; 039CE60A2EAA31CB007B5EED /* FAStatAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAStatAPI.swift; sourceTree = ""; }; @@ -777,6 +805,59 @@ path = Alert; sourceTree = ""; }; + 035589342F2304B800FAEF4A /* AdManager */ = { + isa = PBXGroup; + children = ( + 0355894E2F2AEF0900FAEF4A /* Native */, + 035589432F249CC500FAEF4A /* Banner */, + 035589382F2319EB00FAEF4A /* Open */, + 035589372F2319DD00FAEF4A /* Rewarded */, + 035589352F2305D800FAEF4A /* FAAdManager.swift */, + ); + path = AdManager; + sourceTree = ""; + }; + 035589372F2319DD00FAEF4A /* Rewarded */ = { + isa = PBXGroup; + children = ( + 0355893F2F24924300FAEF4A /* FARewardedAdManager.swift */, + 035589412F24945600FAEF4A /* FATradPlusRewardedAd.swift */, + 035589482F273C5100FAEF4A /* FATradPlusInterstitialAd.swift */, + 0355894A2F274A9400FAEF4A /* FARewardedAdInfo.swift */, + 0355894C2F27530800FAEF4A /* FARewardedAdOverview.swift */, + ); + path = Rewarded; + sourceTree = ""; + }; + 035589382F2319EB00FAEF4A /* Open */ = { + isa = PBXGroup; + children = ( + 0355893D2F2464C100FAEF4A /* FAOpenViewController.swift */, + 035589392F234B3E00FAEF4A /* FAOpenAdManager.swift */, + 0355893B2F234C8300FAEF4A /* FATradPlusOpenAd.swift */, + ); + path = Open; + sourceTree = ""; + }; + 035589432F249CC500FAEF4A /* Banner */ = { + isa = PBXGroup; + children = ( + 035589442F249CF200FAEF4A /* FABannerAdManager.swift */, + 035589462F249D9D00FAEF4A /* FATradPlusBannerAd.swift */, + ); + path = Banner; + sourceTree = ""; + }; + 0355894E2F2AEF0900FAEF4A /* Native */ = { + isa = PBXGroup; + children = ( + 0355894F2F2AEF3700FAEF4A /* FANativeAdManager.swift */, + 035589532F2AF1CB00FAEF4A /* FATradPlusNativeAd.swift */, + 035589572F2B353200FAEF4A /* FATradPlusNativeAdView.swift */, + ); + path = Native; + sourceTree = ""; + }; 039CE6072EAA2F37007B5EED /* AdjustStateManager */ = { isa = PBXGroup; children = ( @@ -1302,6 +1383,7 @@ 03E23A962EAA1A65004A8CEC /* Libs */ = { isa = PBXGroup; children = ( + 035589342F2304B800FAEF4A /* AdManager */, 03E9A78E2EC1AFEA000D1067 /* ActivityManager */, 031FDEE22EB3487700F4CAC7 /* Alert */, 039CE6122EAB0DE1007B5EED /* FAIap */, @@ -2164,15 +2246,18 @@ 031FDEB62EB0B77F00F4CAC7 /* FACoinPackConfirmItemView.swift in Sources */, F35S8138Z362EG3435ME1455 /* CSGleeView.swift in Sources */, 031FDEB42EB0AD7D00F4CAC7 /* FACoinPackConfirmView.swift in Sources */, + 035589362F2305D800FAEF4A /* FAAdManager.swift in Sources */, F31451S3X15B941342J922Q3 /* TConfigCell.swift in Sources */, F3670DZ2KI89TBO3L9L36P57 /* XLoginView.swift in Sources */, F3V24670CK2EGR4595CDQ261 /* AWUModalMageCell.swift in Sources */, + 035589502F2AEF3700FAEF4A /* FANativeAdManager.swift in Sources */, F336143N569M8JG811WM9549 /* XHEedbackDetailView.swift in Sources */, F3F0952W592747Y1H6263E06 /* UCVBbfdebaffdFlowCell.swift in Sources */, F3SUP8DL68BIIEF1B8Z6U863 /* CFQConfigView.swift in Sources */, 031FDEE12EB344AB00F4CAC7 /* FALogin+Facebook.swift in Sources */, F30E153206675C3SJ3974VL1 /* OJQUnechoSectionView.swift in Sources */, F381909BQ5JWXYI119A49469 /* DREychainCell.swift in Sources */, + 0355893A2F234B3E00FAEF4A /* FAOpenAdManager.swift in Sources */, F39R66F983517825QO331145 /* QCenterEfineView.swift in Sources */, F3II3AF834346F516W51V693 /* GAMainRecommendedView.swift in Sources */, 031FDEAE2EB093B100F4CAC7 /* FABuyRecordsModel.swift in Sources */, @@ -2195,7 +2280,10 @@ 03E239652EAA1945004A8CEC /* SceneDelegate.swift in Sources */, 039CE6092EAA2F71007B5EED /* FAAdjustStateManager.swift in Sources */, F333U95746V7VK13QI9275B3 /* UMenuTransformerCell.swift in Sources */, + 035589582F2B353200FAEF4A /* FATradPlusNativeAdView.swift in Sources */, F3140D182F162CFB003DA73F /* FAPayRetainAlertData.swift in Sources */, + 035589472F249D9D00FAEF4A /* FATradPlusBannerAd.swift in Sources */, + 035589402F24924300FAEF4A /* FARewardedAdManager.swift in Sources */, F3Q234J5M18F1Q5G2948P056 /* NPVBoutModalController.swift in Sources */, F38Y7NBX3M0RE4O142264411 /* EZEFlow.swift in Sources */, F363P024H4W1T8LN2546W883 /* YBanner.swift in Sources */, @@ -2205,6 +2293,7 @@ 031FDEC82EB1F89F00F4CAC7 /* FACoinsPackModel.swift in Sources */, F31N0S2575E3YC5AOG80WE90 /* TYElyon.swift in Sources */, F3JX29E3JQ40V23245TS8Z36 /* YRegisterController.swift in Sources */, + 035589422F24945600FAEF4A /* FATradPlusRewardedAd.swift in Sources */, F381171472542RD403O12925 /* QZOast.swift in Sources */, F33I62G51648130G0N6LN003 /* JOLayoutRyptorView.swift in Sources */, F39EH05VP4YX3F00P5162031 /* YFddebcdbeeffcebdfCenterView.swift in Sources */, @@ -2272,6 +2361,7 @@ 039CE6202EAB114B007B5EED /* FAPayDateModel.swift in Sources */, 03E23A4A2EAA1A4E004A8CEC /* FAConsumptionRecordsViewController.swift in Sources */, 031FDED02EB2167200F4CAC7 /* FACoinsPackBuyView.swift in Sources */, + 035589542F2AF1CB00FAEF4A /* FATradPlusNativeAd.swift in Sources */, 03E23A4B2EAA1A4E004A8CEC /* FAMeCoinsView.swift in Sources */, 03E23A4C2EAA1A4E004A8CEC /* FAHomeViewModel.swift in Sources */, 03E23A4D2EAA1A4E004A8CEC /* FAGenresViewController.swift in Sources */, @@ -2282,6 +2372,7 @@ 03E23A512EAA1A4E004A8CEC /* FAConsumptionRecordsCell.swift in Sources */, 03E23A522EAA1A4E004A8CEC /* FARankingListHeaderView.swift in Sources */, 03E23A532EAA1A4E004A8CEC /* FAVideoLockView.swift in Sources */, + 035589452F249CF200FAEF4A /* FABannerAdManager.swift in Sources */, 03E9A7482EB5D2CB000D1067 /* FALogoutAlert.swift in Sources */, 03E23A542EAA1A4E004A8CEC /* FAHomeViewController.swift in Sources */, 03E23A552EAA1A4E004A8CEC /* FAPopularListViewController.swift in Sources */, @@ -2300,6 +2391,7 @@ 03E23A5E2EAA1A4E004A8CEC /* FAHomeMustSeeContentView.swift in Sources */, 03E9A7902EC1B007000D1067 /* FAActivityManager.swift in Sources */, 03E23A5F2EAA1A4E004A8CEC /* FAEpSelectorCell.swift in Sources */, + 0355894B2F274A9400FAEF4A /* FARewardedAdInfo.swift in Sources */, 031FDEEC2EB35DF600F4CAC7 /* FACoinsPackAlert.swift in Sources */, 03E23A602EAA1A4E004A8CEC /* FASearchResultView.swift in Sources */, 03E23A612EAA1A4E004A8CEC /* FAHomeMustSeeContentCell.swift in Sources */, @@ -2338,6 +2430,7 @@ 03E23A7A2EAA1A4E004A8CEC /* FASearchRecordView.swift in Sources */, 03E23A7B2EAA1A4E004A8CEC /* FACollectViewController.swift in Sources */, 03E23A7C2EAA1A4E004A8CEC /* FAMeCell.swift in Sources */, + 0355894D2F27530800FAEF4A /* FARewardedAdOverview.swift in Sources */, 03E9A73A2EB45154000D1067 /* AppDelegate+FAApns.swift in Sources */, 03E23A7D2EAA1A4E004A8CEC /* FAWalletHeaderView.swift in Sources */, 03E23A7E2EAA1A4E004A8CEC /* FAPlayerProgressView.swift in Sources */, @@ -2369,6 +2462,7 @@ F3774560U03XA8151BTQ2Z61 /* HYLLayoutView.swift in Sources */, F3N85463XSRG9VFK665G9028 /* XKRefreshCell.swift in Sources */, 039CE6282EAB50A9007B5EED /* FAStoreCoinsView.swift in Sources */, + 035589492F273C5100FAEF4A /* FATradPlusInterstitialAd.swift in Sources */, 03E9A7402EB49BE6000D1067 /* FAUpdatesAlert.swift in Sources */, F35K41930D96476I83FHZ0D9 /* YLZFableonAlignmentCell.swift in Sources */, F3M8439X72Q55JY9G8U502D9 /* DXYFire.swift in Sources */, @@ -2388,6 +2482,7 @@ 03E239972EAA1A29004A8CEC /* FANetworkManager.swift in Sources */, 03E239982EAA1A29004A8CEC /* UIScrollView+FARefresh.swift in Sources */, 03E239992EAA1A29004A8CEC /* FANavigationController.swift in Sources */, + 0355893C2F234C8300FAEF4A /* FATradPlusOpenAd.swift in Sources */, 03E2399A2EAA1A29004A8CEC /* FAViewController.swift in Sources */, 03E2399B2EAA1A29004A8CEC /* FAWebMessageModel.swift in Sources */, 03E2399C2EAA1A29004A8CEC /* FAGradientButton.swift in Sources */, @@ -2435,6 +2530,7 @@ F395KWCS21F322A36E293006 /* IHAVeloriaButton.swift in Sources */, F31PD82C37A3078M87873G8T /* FFCheck.swift in Sources */, F36588YE88493S7167N94531 /* MProgressBoutCell.swift in Sources */, + 0355893E2F2464C100FAEF4A /* FAOpenViewController.swift in Sources */, F35TM2110T9T394C6D0214G9 /* EXYAlignmentHiveView.swift in Sources */, F32G5ID338260A2W78SS4618 /* TCFableonCell.swift in Sources */, F31E84U5Y6YW6430Z54X1K40 /* UCHVion.swift in Sources */, @@ -2734,7 +2830,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Fableon/Fableon.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 6XALB8RSYF; "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; GENERATE_INFOPLIST_FILE = YES; @@ -2755,7 +2851,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.6; + MARKETING_VERSION = 1.0.7; PRODUCT_BUNDLE_IDENTIFIER = com.hn.qinjiu.fableon; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; @@ -2777,7 +2873,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Fableon/Fableon.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 6XALB8RSYF; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Fableon/Source/Info.plist; @@ -2797,7 +2893,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.6; + MARKETING_VERSION = 1.0.7; PRODUCT_BUNDLE_IDENTIFIER = com.hn.qinjiu.fableon; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; diff --git a/Fableon/App/AppDelegate+FAConfig.swift b/Fableon/App/AppDelegate+FAConfig.swift index bbcf3a2..e6132bb 100644 --- a/Fableon/App/AppDelegate+FAConfig.swift +++ b/Fableon/App/AppDelegate+FAConfig.swift @@ -36,6 +36,7 @@ extension AppDelegate { func fa_registThirdparty(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) { ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions) + FAAdManager.initSdk() } } diff --git a/Fableon/App/SceneDelegate.swift b/Fableon/App/SceneDelegate.swift index 7e05b42..76047b1 100644 --- a/Fableon/App/SceneDelegate.swift +++ b/Fableon/App/SceneDelegate.swift @@ -39,6 +39,10 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { requestFirebase() requestApns() + //加载开屏广告 + FAOpenAdManager.manager.showAdIfAvailable() + //加载激励广告 + FARewardedAdManager.manager.load() } func sceneDidDisconnect(_ scene: UIScene) { @@ -98,6 +102,8 @@ extension SceneDelegate { let hasOpenApp = UserDefaults.standard.object(forKey: kFAHasBeenOpenedAPPDefaultsKey) as? Bool if hasOpenApp != true { + //首次安装不展示广告 + FAOpenAdManager.manager.openAdVC.view.isHidden = true let vc = FAAppStartViewController() vc.openAppBlock = { [weak self] in guard let self = self else { return } @@ -117,7 +123,7 @@ extension SceneDelegate { FAAdjustStateManager.manager.isOpenApp = true window?.rootViewController = FATabBarController() -// window?.makeKeyAndVisible() +// window?.addSubview(FAOpenAdManager.manager.openAdVC.view) } } diff --git a/Fableon/Object/Base/Controller/FAViewController.swift b/Fableon/Object/Base/Controller/FAViewController.swift index f8c3b42..a73eea0 100644 --- a/Fableon/Object/Base/Controller/FAViewController.swift +++ b/Fableon/Object/Base/Controller/FAViewController.swift @@ -33,6 +33,10 @@ class FAViewController: UIViewController, JXSegmentedListContainerViewListDelega } } + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + FAOpenAdManager.manager.vcAllowedShowAd = true + } func handleHeaderRefresh(_ completer: (() -> Void)?) { completer?() diff --git a/Fableon/Object/Base/Request/FAAPI/FAAPI.swift b/Fableon/Object/Base/Request/FAAPI/FAAPI.swift index 8cd1083..6e8104a 100644 --- a/Fableon/Object/Base/Request/FAAPI/FAAPI.swift +++ b/Fableon/Object/Base/Request/FAAPI/FAAPI.swift @@ -266,6 +266,39 @@ struct FAAPI { } } + ///获取激励广告数据 + static func requestRewardedAdOverview(completer: ((_ model: [FARewardedAdOverview]?) -> Void)?) { + + FANetworkManager.manager.request(FABaseURL + "/ad/watchAdOverview", + method: .get, + parameters: nil, + isLoding: false, + isToast: true) { (response: FANetworkManager.Response<[FARewardedAdOverview]>) in + completer?(response.data) + } + } + + ///广告解锁 + static func requestAdUnlockVideo(shortPlayId: String, videoId: String, completer: ((_ model: FAVideoUnlockResult?) -> Void)?) { + + let parameters = [ + "short_play_id" : shortPlayId, + "video_id" : videoId, + "ads_id" : "", + "ads_platform_key" : "", + "trans_id" : "", + "watch_num" : "1" + ] + + FANetworkManager.manager.request(FABaseURL + "/viewAdsUnlockVideo", + method: .post, + parameters: parameters, + isLoding: true, + isToast: true) { (response: FANetworkManager.Response) in + completer?(response.data) + } + } + static func requestVersionUpdateData(completer: ((_ model: FAVersionUpdateModel?) -> Void)?) { FANetworkManager.manager.request(FABaseURL + "/customer/versionControl", diff --git a/Fableon/Object/Class/Player/V/FAPlayerDetailControlView.swift b/Fableon/Object/Class/Player/V/FAPlayerDetailControlView.swift index 5b551db..b63c102 100644 --- a/Fableon/Object/Class/Player/V/FAPlayerDetailControlView.swift +++ b/Fableon/Object/Class/Player/V/FAPlayerDetailControlView.swift @@ -55,6 +55,12 @@ class FAPlayerDetailControlView: JXPlayerListControlView { override var isCurrent: Bool { didSet { playButton.setNeedsUpdateConfiguration() + if isCurrent { + self.bannerAdManager.loadAd() + } else { + self.bannerAdManager.cleanAd() + } + self.updateBannerAdLayout() } } @@ -102,6 +108,7 @@ class FAPlayerDetailControlView: JXPlayerListControlView { let button = UIButton(configuration: config, primaryAction: UIAction(handler: { [weak self] _ in self?.fa_viewModel?.userSwitchPlayAndPause() })) + button.isUserInteractionEnabled = false button.configurationUpdateHandler = { [weak self] button in guard let self = self else { return } @@ -147,7 +154,17 @@ class FAPlayerDetailControlView: JXPlayerListControlView { return button }() + private lazy var bannerAdView: UIView = { + let view = UIView() + return view + }() + private lazy var bannerAdManager: FABannerAdManager = { + let manager = FABannerAdManager() + manager.contentView = self.bannerAdView + manager.delegate = self + return manager + }() deinit { NotificationCenter.default.removeObserver(self) @@ -198,6 +215,25 @@ class FAPlayerDetailControlView: JXPlayerListControlView { collectButton.isSelected = state } + + private func updateBannerAdLayout() { + self.bannerAdView.isHidden = !self.bannerAdManager.isAdAvailable + if self.bannerAdManager.isAdAvailable { + epButton.view.snp.updateConstraints { make in + make.bottom.equalToSuperview().offset(-(UIScreen.safeBottom + 10 + 50 + 10)) + } + } else { + epButton.view.snp.updateConstraints { make in + make.bottom.equalToSuperview().offset(-(UIScreen.safeBottom + 10)) + } + } + } + + override func singleTapEvent() { + super.singleTapEvent() + self.fa_viewModel?.userSwitchPlayAndPause() + } + } extension FAPlayerDetailControlView { @@ -210,7 +246,7 @@ extension FAPlayerDetailControlView { addSubview(shortNameLabel) addSubview(playButton) addSubview(collectButton) - + addSubview(bannerAdView) epButton.view.snp.makeConstraints { make in make.left.equalToSuperview().offset(16) @@ -246,8 +282,20 @@ extension FAPlayerDetailControlView { make.height.equalTo(44) } - + bannerAdView.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.left.equalToSuperview().offset(16) + make.bottom.equalToSuperview().offset(-(UIScreen.safeBottom + 10)) + make.height.equalTo(50) + } } } + +extension FAPlayerDetailControlView: FABannerAdManagerDelegate { + + func fa_bannerAdManagerDidLoadFinish(manager: FABannerAdManager) { + self.updateBannerAdLayout() + } +} diff --git a/Fableon/Object/Class/Player/VC/FAPlayerDetailViewController.swift b/Fableon/Object/Class/Player/VC/FAPlayerDetailViewController.swift index ca7fb83..11ae3b0 100644 --- a/Fableon/Object/Class/Player/VC/FAPlayerDetailViewController.swift +++ b/Fableon/Object/Class/Player/VC/FAPlayerDetailViewController.swift @@ -8,6 +8,7 @@ import UIKit import JXPlayer import FDFullscreenPopGesture +import SnapKit class FAPlayerDetailViewController: JXPlayerListViewController { @@ -30,22 +31,45 @@ class FAPlayerDetailViewController: JXPlayerListViewController { return self.viewModel as! FAShortDetailViewModel } + private var epText: String? { + didSet { + returnButton.setNeedsUpdateConfiguration() + } + } + private lazy var returnButton: UIButton = { - let button = UIButton(type: .custom) - button.setImage(UIImage(named: "Frame 3011"), for: .normal) - button.addAction(UIAction(handler: { [weak self] _ in + var configuration = UIButton.Configuration.plain() + configuration.image = UIImage(named: "Frame 3011") + configuration.imagePadding = 4 + configuration.contentInsets = .init(top: 0, leading: 10, bottom: 0, trailing: 10) + + let button = UIButton(configuration: configuration, primaryAction: UIAction(handler: { [weak self] _ in self?.handleBackButton() - }), for: .touchUpInside) + })) + + button.configurationUpdateHandler = { [weak self] button in + guard let self = self else { return } + var newConfiguration = button.configuration + if let text = self.epText { + newConfiguration?.attributedTitle = AttributedString(text, attributes: AttributeContainer([ + .font : UIFont.font(ofSize: 18, weight: .regular), + .foregroundColor : UIColor.white + ])) + } else { + newConfiguration?.attributedTitle = nil + } + button.configuration = newConfiguration + } + + return button }() - private lazy var epLabel: UILabel = { - let label = UILabel() - label.font = .font(ofSize: 18, weight: .regular) - label.textColor = .init(named: .color_FFFFFF) - return label + private(set) lazy var nativeAdContentView: UIView = { + let view = UIView() + view.isHidden = true + return view }() - override func viewDidLoad() { super.viewDidLoad() @@ -59,6 +83,8 @@ class FAPlayerDetailViewController: JXPlayerListViewController { requestDetailList() + self.fa_viewModel.loadNativeAd() + fa_setupLayout() self.fa_viewModel.requestRecommandData() @@ -71,6 +97,7 @@ class FAPlayerDetailViewController: JXPlayerListViewController { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) + FAOpenAdManager.manager.vcAllowedShowAd = false } override func viewDidDisappear(_ animated: Bool) { @@ -142,19 +169,21 @@ class FAPlayerDetailViewController: JXPlayerListViewController { extension FAPlayerDetailViewController { private func fa_setupLayout() { + view.addSubview(nativeAdContentView) view.addSubview(returnButton) - view.addSubview(epLabel) + + nativeAdContentView.snp.remakeConstraints { make in + make.center.equalToSuperview() + make.width.equalTo(self.fa_viewModel.nativeAdManager.contentSize.width) + make.height.equalTo(self.fa_viewModel.nativeAdManager.contentSize.height) + } returnButton.snp.makeConstraints { make in - make.left.equalToSuperview().offset(16) - make.top.equalToSuperview().offset(UIScreen.safeTop) + make.left.equalToSuperview().offset(6) + make.top.equalTo(view.safeAreaLayoutGuide) make.height.equalTo(44) } - epLabel.snp.makeConstraints { make in - make.centerY.equalTo(returnButton) - make.left.equalTo(returnButton.snp.right).offset(4) - } } } @@ -185,7 +214,7 @@ extension FAPlayerDetailViewController: JXPlayerListViewControllerDelegate, JXPl func jx_playerListViewController(_ viewController: JXPlayerListViewController, didChangeIndexPathForVisible indexPath: IndexPath) { let model = self.fa_viewModel.dataArr[indexPath.section].episodeList?[indexPath.row] - epLabel.text = "Ep.\(model?.episode ?? "")" + self.epText = "Ep.\(model?.episode ?? "")" } func jx_shouldAutoScrollNextEpisode(_ viewController: JXPlayerListViewController) -> Bool { diff --git a/Fableon/Object/Class/Player/VM/FAShortDetailViewModel.swift b/Fableon/Object/Class/Player/VM/FAShortDetailViewModel.swift index a11ed6d..3b91aae 100644 --- a/Fableon/Object/Class/Player/VM/FAShortDetailViewModel.swift +++ b/Fableon/Object/Class/Player/VM/FAShortDetailViewModel.swift @@ -8,6 +8,7 @@ import SwiftUI import JXPlayer import YYText +import SnapKit //@MainActor class FAShortDetailViewModel: JXPlayerListViewModel, ObservableObject { @@ -45,6 +46,21 @@ class FAShortDetailViewModel: JXPlayerListViewModel, ObservableObject { private var payDataRequest: FAPayDataRequest? + override var isPlaying: Bool { + didSet { + if !self.isPlaying { + self.showNativeAd() + } else { + self.dismissNativeAd() + } + } + } + + private(set) lazy var nativeAdManager: FANativeAdManager = { + let manager = FANativeAdManager() + return manager + }() + func requestDetailData(indexPath: IndexPath? = nil, completer: ((_ code: Int) -> Void)?) { isShowRecommand = false @@ -236,12 +252,14 @@ extension FAShortDetailViewModel { private func _showPayRetainAlert(_ videoInfo: FAVideoInfoModel) { - payDataRequest = FAPayDataRequest() payDataRequest?.requestPayRetainInfo { [weak self] model in guard let self = self else { return } - guard let model = model else { return } + guard let model = model else { + self.showRewardedAd() + return + } let view = FAPayRetainAlert() view.model = model @@ -250,10 +268,63 @@ extension FAShortDetailViewModel { guard let self = self else { return } self.requestDetailData(indexPath: self.currentIndexPath, completer: nil) } + view.didDismissHandle = { [weak self] in + guard let self = self else { return } + self.showRewardedAd() + } view.show(in: FATool.keyWindow) } } + + ///展示激励广告 + private func showRewardedAd() { + let manager = FARewardedAdManager.manager + if manager.isAdAvailable { + manager.delegate = self + manager.show() + } + } + + ///加载原生广告 + func loadNativeAd() { + self.nativeAdManager.load() + } + + ///展示原生广告 + private func showNativeAd() { + guard let view = (self.playerListVC as? FAPlayerDetailViewController)?.nativeAdContentView else { return } + guard self.nativeAdManager.isAdAvailable else { return } + guard view.isHidden else { return } + + view.isHidden = false + self.nativeAdManager.contentView = view + self.nativeAdManager.show() + } + + private func dismissNativeAd() { + guard let view = (self.playerListVC as? FAPlayerDetailViewController)?.nativeAdContentView else { return } + + view.isHidden = true + } +} + +//MARK: FARewardedAdManagerDelegate +extension FAShortDetailViewModel: FARewardedAdManagerDelegate { + + func fa_rewardedAdManagerDidDismiss(adManager: FARewardedAdManager) { + guard let videoInfo = self.currentCell?.model as? FAVideoInfoModel else { return } + guard let shortPlayId = videoInfo.short_play_id else { return } + guard let videoId = videoInfo.short_play_video_id else { return } + + FAAPI.requestAdUnlockVideo(shortPlayId: shortPlayId, videoId: videoId) { [weak self] model in + guard let self = self else { return } + guard model?.status == .success else { return } + + self.requestDetailData(indexPath: self.currentIndexPath, completer: nil) + } + + } } extension FAShortDetailViewModel { diff --git a/Fableon/Object/Class/Recommend/C/FARecommendViewController.swift b/Fableon/Object/Class/Recommend/C/FARecommendViewController.swift index 0baf1c4..eb6ca42 100644 --- a/Fableon/Object/Class/Recommend/C/FARecommendViewController.swift +++ b/Fableon/Object/Class/Recommend/C/FARecommendViewController.swift @@ -61,6 +61,11 @@ class FARecommendViewController: JXPlayerListViewController { self.navigationController?.setNavigationBarHidden(true, animated: true) } + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + FAOpenAdManager.manager.vcAllowedShowAd = false + } + override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) self.viewModel.currentCell?.pause() diff --git a/Fableon/Object/Class/Store/V/FAStoreCoinsBigCell.swift b/Fableon/Object/Class/Store/V/FAStoreCoinsBigCell.swift index 942193c..33c6c48 100644 --- a/Fableon/Object/Class/Store/V/FAStoreCoinsBigCell.swift +++ b/Fableon/Object/Class/Store/V/FAStoreCoinsBigCell.swift @@ -11,11 +11,11 @@ class FAStoreCoinsBigCell: FAStoreCoinsCell { override var fa_isSelected: Bool { didSet { - if fa_isSelected { +// if fa_isSelected { bgImageView.image = UIImage(named: "Rectangle 6216") - } else { - bgImageView.image = UIImage(named: "Rectangle 6217") - } +// } else { +// bgImageView.image = UIImage(named: "Rectangle 6217") +// } } } @@ -24,14 +24,15 @@ class FAStoreCoinsBigCell: FAStoreCoinsCell { let coins = model?.coins ?? 0 let sendCoins = model?.send_coins ?? 0 - coinCountLabel.text = "\(coins)" + coinCountLabel.text = "\(coins + sendCoins)" priceLabel.text = (model?.currency ?? "") + " " + (model?.price ?? "") if sendCoins > 0 { sendCoinsLabel.isHidden = false sendCoinsRatioImageView.isHidden = false - sendCoinsLabel.text = "+\(sendCoins) " + "fableon_coins".localized +// sendCoinsLabel.text = "+\(sendCoins) " + "fableon_coins".localized + sendCoinsLabel.text = "\(coins)+\(sendCoins)" let ratio = String(format: "%.0f", CGFloat(sendCoins) / CGFloat(coins) * 100) sendCoinsRatioLabel.text = "+\(ratio)%" @@ -53,14 +54,19 @@ class FAStoreCoinsBigCell: FAStoreCoinsCell { return imageView }() + private lazy var coinsView: UIView = { + let view = UIView() + return view + }() + private lazy var coinImageView: UIImageView = { - let imageView = UIImageView(image: UIImage(named: "coins_icon_04")) + let imageView = UIImageView(image: UIImage(named: "coins_icon_09")) return imageView }() private lazy var coinCountLabel: UILabel = { let label = UILabel() - label.font = .font(ofSize: 16, weight: .medium) + label.font = .font(ofSize: 20, weight: .bold) label.textColor = .FFFFFF return label }() @@ -68,7 +74,7 @@ class FAStoreCoinsBigCell: FAStoreCoinsCell { private lazy var sendCoinsLabel: UILabel = { let label = UILabel() label.font = .font(ofSize: 10, weight: .medium) - label.textColor = ._000000 + label.textColor = ._000000.withAlphaComponent(0.5) return label }() @@ -91,7 +97,7 @@ class FAStoreCoinsBigCell: FAStoreCoinsCell { private lazy var priceLabel: UILabel = { let label = UILabel() - label.font = .font(ofSize: 14, weight: .heavy) + label.font = .font(ofSize: 16, weight: .bold) label.textColor = ._000000 return label }() @@ -117,9 +123,10 @@ extension FAStoreCoinsBigCell { private func fa_setupLayout() { contentView.addSubview(bgImageView) - bgImageView.addSubview(coinImageView) - bgImageView.addSubview(coinCountLabel) - bgImageView.addSubview(sendCoinsLabel) + bgImageView.addSubview(coinsView) + coinsView.addSubview(coinImageView) + coinsView.addSubview(coinCountLabel) + coinsView.addSubview(sendCoinsLabel) bgImageView.addSubview(sendCoinsRatioImageView) sendCoinsRatioImageView.addSubview(sendCoinsRatioLabel) contentView.addSubview(priceBgView) @@ -130,19 +137,24 @@ extension FAStoreCoinsBigCell { make.left.right.top.equalToSuperview() } + coinsView.snp.makeConstraints { make in + make.center.equalToSuperview() + } + coinImageView.snp.makeConstraints { make in - make.centerX.equalToSuperview() - make.top.equalToSuperview().offset(7) + make.top.bottom.equalToSuperview() + make.left.equalToSuperview() } coinCountLabel.snp.makeConstraints { make in - make.centerX.equalToSuperview() - make.top.equalTo(coinImageView.snp.bottom).offset(4) + make.centerY.equalToSuperview() + make.left.equalTo(coinImageView.snp.right).offset(2) } sendCoinsLabel.snp.makeConstraints { make in - make.centerX.equalToSuperview() - make.top.equalTo(coinCountLabel.snp.bottom).offset(0) + make.centerY.equalToSuperview() + make.left.equalTo(coinCountLabel.snp.right).offset(2) + make.right.equalToSuperview() } sendCoinsRatioImageView.snp.makeConstraints { make in @@ -156,12 +168,13 @@ extension FAStoreCoinsBigCell { } priceBgView.snp.makeConstraints { make in - make.centerX.equalToSuperview() + make.centerX.equalToSuperview().offset(-8) make.bottom.equalToSuperview() } priceLabel.snp.makeConstraints { make in make.center.equalToSuperview() + make.left.equalToSuperview().offset(15) } hotImageView.snp.makeConstraints { make in diff --git a/Fableon/Object/Class/Store/V/FAStoreCoinsView.swift b/Fableon/Object/Class/Store/V/FAStoreCoinsView.swift index d7a909e..4575ac8 100644 --- a/Fableon/Object/Class/Store/V/FAStoreCoinsView.swift +++ b/Fableon/Object/Class/Store/V/FAStoreCoinsView.swift @@ -124,7 +124,7 @@ extension FAStoreCoinsView { private func bigLayoutSection() -> NSCollectionLayoutSection { let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(0.5), heightDimension: .fractionalHeight(1))) - let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .absolute(100)), subitems: [item]) + let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .absolute(89)), subitems: [item]) group.interItemSpacing = .fixed(1) let layoutSection = NSCollectionLayoutSection(group: group) diff --git a/Fableon/Object/Libs/AdManager/Banner/FABannerAdManager.swift b/Fableon/Object/Libs/AdManager/Banner/FABannerAdManager.swift new file mode 100644 index 0000000..f7e038d --- /dev/null +++ b/Fableon/Object/Libs/AdManager/Banner/FABannerAdManager.swift @@ -0,0 +1,136 @@ +// +// FABannerAdManager.swift +// Fableon +// +// Created by 湖北秦九 on 2026/1/24. +// + +import UIKit + +@objc protocol FABannerAdManagerDelegate: NSObjectProtocol { + ///广告加载失败 + @objc optional func fa_bannerAdManager(manager: FABannerAdManager, didLoadFail error: Error) + ///广告加载成功 + @objc optional func fa_bannerAdManagerDidLoadFinish(manager: FABannerAdManager) + ///广告被展示 + @objc optional func fa_bannerAdManagerDidShow(manager: FABannerAdManager) + /// 广告展示失败 + @objc optional func fa_bannerAdManager(manager: FABannerAdManager, didDisplayFail error: Error) + ///广告被关闭 + @objc optional func fa_bannerAdManagerDidDismiss(manager: FABannerAdManager) + ///广告被点击 + @objc optional func fa_bannerAdManagerDidClick(manager: FABannerAdManager) +} + + +protocol FABannerAdDelegate: NSObjectProtocol { + ///广告加载失败 + func fa_bannerAd(bannerAd: FABannerAd, didLoadFail error: Error) + ///广告加载成功 + func fa_bannerAdDidLoadFinish(bannerAd: FABannerAd) + ///广告被展示 + func fa_bannerAdDidShow(bannerAd: FABannerAd) + ///广告展示失败 + func fa_bannerAd(bannerAd: FABannerAd, didDisplayFail error: Error) + ///广告被关闭 + func fa_bannerAdDidDismiss(bannerAd: FABannerAd) + ///广告被点击 + func fa_bannerAdDidClick(ad: FABannerAd) +} + +protocol FABannerAd: NSObjectProtocol { + + var delegate: FABannerAdDelegate? { get set } + + var adView: UIView? { get } + + var adPlatform: FAAdPlatform { get } + + var adType: FAAdType { get } + + var adUnitID: String { get } + + var isReady: Bool { get set } + + func loadAd() + +} + +class FABannerAdManager: NSObject { + + + private(set) var bannerAd: FABannerAd? { + didSet { + oldValue?.adView?.removeFromSuperview() + oldValue?.delegate = nil + } + } + + weak var delegate: FABannerAdManagerDelegate? + + + ///外部传入,用来承载广告的视图 + var contentView: UIView? { + didSet { + self.updateLayout() + } + } + + var isAdAvailable: Bool { + return bannerAd?.isReady ?? false + } + + func loadAd() { + let ad = FATradPlusBannerAd() + ad.delegate = self + + self.bannerAd = ad + + self.updateLayout() + self.bannerAd?.loadAd() + } + + func cleanAd() { + self.bannerAd = nil + } + + private func updateLayout() { + if let adView = bannerAd?.adView, let contentView = self.contentView { + contentView.addSubview(adView) + adView.frame = contentView.bounds + adView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + } + } +} + + +//MARK: FABannerAdManager +extension FABannerAdManager: FABannerAdDelegate { + + func fa_bannerAd(bannerAd: any FABannerAd, didDisplayFail error: any Error) { + self.delegate?.fa_bannerAdManager?(manager: self, didDisplayFail: error) + } + + func fa_bannerAd(bannerAd: any FABannerAd, didLoadFail error: any Error) { + self.delegate?.fa_bannerAdManager?(manager: self, didLoadFail: error) + } + + func fa_bannerAdDidLoadFinish(bannerAd: any FABannerAd) { + self.delegate?.fa_bannerAdManagerDidLoadFinish?(manager: self) + } + + func fa_bannerAdDidShow(bannerAd: any FABannerAd) { + self.delegate?.fa_bannerAdManagerDidShow?(manager: self) + } + + func fa_bannerAdDidDismiss(bannerAd: any FABannerAd) { + self.delegate?.fa_bannerAdManagerDidDismiss?(manager: self) + } + + func fa_bannerAdDidClick(ad: any FABannerAd) { + self.delegate?.fa_bannerAdManagerDidClick?(manager: self) + } + + + +} diff --git a/Fableon/Object/Libs/AdManager/Banner/FATradPlusBannerAd.swift b/Fableon/Object/Libs/AdManager/Banner/FATradPlusBannerAd.swift new file mode 100644 index 0000000..f93da65 --- /dev/null +++ b/Fableon/Object/Libs/AdManager/Banner/FATradPlusBannerAd.swift @@ -0,0 +1,88 @@ +// +// FATradPlusBannerAd.swift +// Fableon +// +// Created by 湖北秦九 on 2026/1/24. +// + +import UIKit +#if canImport(TradPlusAds) +import TradPlusAds +#endif + +class FATradPlusBannerAd: NSObject, FABannerAd { + +#if canImport(TradPlusAds) + private lazy var bannerView: TradPlusAdBanner = { + let view = TradPlusAdBanner() + view.delegate = self + view.translatesAutoresizingMaskIntoConstraints = false + // view.adSize = . + return view + }() +#endif + + weak var delegate: FABannerAdDelegate? + + var adView: UIView? { +#if canImport(TradPlusAds) + return self.bannerView +#else + return nil +#endif + } + + var isReady: Bool = false + + var adPlatform: FAAdPlatform { + return .tradPlus + } + + var adType: FAAdType { + return .banner + } + + var adUnitID: String { + return self.adPlatform.bannerUnitId + } + + func loadAd() { +#if canImport(TradPlusAds) + self.bannerView.setAdUnitID(self.adUnitID) + self.bannerView.loadAd(withSceneId: nil) +#endif + } + +} + +#if canImport(TradPlusAds) +extension FATradPlusBannerAd: TradPlusADBannerDelegate { + + func tpBannerAdLoaded(_ adInfo: [AnyHashable : Any]) { + self.isReady = true + debugLog("+++++++++++广告加载成功") + self.delegate?.fa_bannerAdDidLoadFinish(bannerAd: self) + } + + func tpBannerAdLoadFailWithError(_ error: any Error) { + self.delegate?.fa_bannerAd(bannerAd: self, didLoadFail: error) + } + + func tpBannerAdImpression(_ adInfo: [AnyHashable : Any]) { + debugLog("+++++++++++广告加载展示成功") + self.delegate?.fa_bannerAdDidShow(bannerAd: self) + } + + func tpBannerAdShow(_ adInfo: [AnyHashable : Any], didFailWithError error: any Error) { + self.delegate?.fa_bannerAd(bannerAd: self, didDisplayFail: error) + } + + func tpBannerAdClicked(_ adInfo: [AnyHashable : Any]) { + self.delegate?.fa_bannerAdDidClick(ad: self) + } + + func viewControllerForPresentingModalView() -> UIViewController? { + return nil + } +} +#endif diff --git a/Fableon/Object/Libs/AdManager/FAAdManager.swift b/Fableon/Object/Libs/AdManager/FAAdManager.swift new file mode 100644 index 0000000..608cba2 --- /dev/null +++ b/Fableon/Object/Libs/AdManager/FAAdManager.swift @@ -0,0 +1,87 @@ +// +// FAAdManager.swift +// Fableon +// +// Created by 湖北秦九 on 2026/1/23. +// + +import UIKit +import SmartCodable +#if canImport(TradPlusAds) +import TradPlusAds +#endif + + +class FAAdManager: NSObject { + + static func initSdk() { +#if canImport(TradPlusAds) +#if DEBUG + TradPlus.setLogLevel(MSLogLevelAll) +#endif + TradPlus.initSDK("8C768B1A89BA057E47D752181A7BDA21") { error in + if let error = error { + debugLog(error) + } else { + debugLog("TradPlus 初始化成功") + } + } +#endif + + } + +} + +enum FAAdType { + case rewarded + case interstitial + case banner + case open + case native +} + +enum FAAdPlatform: String, SmartCaseDefaultable { + case tradPlus = "tradplus" + + ///激励广告单元Id + var rewardedUnitId: String { + switch self { + case .tradPlus: + return "E35A9B622C1125CB6EDFC288F22CDB22" + } + } + + ///开屏广告单元Id + var openUnitId: String { + switch self { + case .tradPlus: + return "67B5E393DF8D80325B0CC1055B5A2122" + } + } + + ///横幅广告单元Id + var bannerUnitId: String { + switch self { + case .tradPlus: + return "E92BEE12E188BCD15834075F5A32A922" + } + } + + ///插屏广告 + var interstitialUnitId: String { + switch self { + case .tradPlus: + return "F8303BAF407F8ED3642B1F8B703D4822" + } + } + + ///原生广告 + var nativeUnitId: String { + switch self { + case .tradPlus: + return "C4463BAD71D16B4B840703EAEBD0D422" + } + } + +} + diff --git a/Fableon/Object/Libs/AdManager/Native/FANativeAdManager.swift b/Fableon/Object/Libs/AdManager/Native/FANativeAdManager.swift new file mode 100644 index 0000000..2f8c05b --- /dev/null +++ b/Fableon/Object/Libs/AdManager/Native/FANativeAdManager.swift @@ -0,0 +1,145 @@ +// +// FANativeAdManager.swift +// Fableon +// +// Created by 湖北秦九 on 2026/1/29. +// + +import UIKit + +@objc protocol FANativeAdManagerDelegate: NSObjectProtocol { + ///广告加载失败 + @objc optional func fa_nativeAdManager(manager: FANativeAdManager, didLoadFail error: Error) + ///广告加载成功 + @objc optional func fa_nativeAdManagerDidLoadFinish(manager: FANativeAdManager) + ///广告被展示 + @objc optional func fa_nativeAdManagerDidShow(manager: FANativeAdManager) + /// 广告展示失败 + @objc optional func fa_nativeAdManager(manager: FANativeAdManager, didDisplayFail error: Error) + ///广告被关闭 + @objc optional func fa_nativeAdManagerDidDismiss(manager: FANativeAdManager) + ///广告被点击 + @objc optional func fa_nativeAdManagerDidClick(manager: FANativeAdManager) +} + + +protocol FANativeAdDelegate: NSObjectProtocol { + ///广告加载失败 + func fa_nativeAd(nativeAd: FANativeAd, didLoadFail error: Error) + ///广告加载成功 + func fa_nativeAdDidLoadFinish(nativeAd: FANativeAd) + ///广告被展示 + func fa_nativeAdDidShow(nativeAd: FANativeAd) + ///广告展示失败 + func fa_nativeAd(nativeAd: FANativeAd, didDisplayFail error: Error) + ///广告被关闭 + func fa_nativeAdDidDismiss(nativeAd: FANativeAd) + ///广告被点击 + func fa_nativeAdDidClick(nativeAd: FANativeAd) +} + +protocol FANativeAd: NSObjectProtocol { + + var delegate: FANativeAdDelegate? { get set } + + var adView: UIView? { get set } + + var adSize: CGSize? { get set } + + var adPlatform: FAAdPlatform { get } + + var adType: FAAdType { get } + + var adUnitID: String { get } + + var isReady: Bool { get } + + func loadAd() + func show() + + +} + +class FANativeAdManager: NSObject { + + weak var delegate: FANativeAdManagerDelegate? + + ///外部传入,用来承载广告的视图 + var contentView: UIView? { + didSet { + self.nativeAd?.adView = contentView + } + } + + let contentSize: CGSize = .init(width: 300, height: 400) + + var isAdAvailable: Bool { + return nativeAd?.isReady ?? false + } + + ///广告是否在加载中 + private(set) var isLoadingAd = false + + ///是否展示过 + var hasShow = false + + + private var nativeAd: FANativeAd? { + didSet { + oldValue?.delegate = nil + nativeAd?.delegate = self + } + } + + + + func load() { + guard !self.isLoadingAd else { return } + + self.isLoadingAd = true + self.nativeAd = FATradPlusNativeAd() + self.nativeAd?.adSize = self.contentSize + self.nativeAd?.adView = contentView + self.nativeAd?.delegate = self + self.nativeAd?.loadAd() + } + + func show() { + guard !hasShow else { return } + self.hasShow = true + self.nativeAd?.show() + } + +} + +extension FANativeAdManager: FANativeAdDelegate { + + func fa_nativeAdDidLoadFinish(nativeAd: any FANativeAd) { + self.isLoadingAd = false + self.delegate?.fa_nativeAdManagerDidLoadFinish?(manager: self) + } + + func fa_nativeAdDidShow(nativeAd: any FANativeAd) { + self.delegate?.fa_nativeAdManagerDidShow?(manager: self) + } + + func fa_nativeAd(nativeAd: any FANativeAd, didLoadFail error: any Error) { + self.isLoadingAd = false + self.delegate?.fa_nativeAdManager?(manager: self, didLoadFail: error) + } + + func fa_nativeAd(nativeAd: any FANativeAd, didDisplayFail error: any Error) { + self.delegate?.fa_nativeAdManager?(manager: self, didDisplayFail: error) + } + + func fa_nativeAdDidDismiss(nativeAd: any FANativeAd) { + self.delegate?.fa_nativeAdManagerDidDismiss?(manager: self) + } + + func fa_nativeAdDidClick(nativeAd: any FANativeAd) { + self.delegate?.fa_nativeAdManagerDidClick?(manager: self) + } + + + +} diff --git a/Fableon/Object/Libs/AdManager/Native/FATradPlusNativeAd.swift b/Fableon/Object/Libs/AdManager/Native/FATradPlusNativeAd.swift new file mode 100644 index 0000000..0591f3c --- /dev/null +++ b/Fableon/Object/Libs/AdManager/Native/FATradPlusNativeAd.swift @@ -0,0 +1,103 @@ +// +// FATradPlusNativeAd.swift +// Fableon +// +// Created by 湖北秦九 on 2026/1/29. +// + +import UIKit +#if canImport(TradPlusAds) +import TradPlusAds +#endif + +class FATradPlusNativeAd: NSObject, FANativeAd { + +#if canImport(TradPlusAds) + private var nativeAd: TradPlusAdNative? +#endif + + weak var delegate: FANativeAdDelegate? + + var adView: UIView? + + var adSize: CGSize? + + var adPlatform: FAAdPlatform { + return .tradPlus + } + + var adType: FAAdType { + return .native + } + + var adUnitID: String { + return adPlatform.nativeUnitId + } + + var isReady: Bool { +#if canImport(TradPlusAds) + return self.nativeAd?.isAdReady ?? false +#else + return false +#endif + } + + func loadAd() { +#if canImport(TradPlusAds) + guard let adSize = self.adSize else { return } + self.nativeAd = TradPlusAdNative() + self.nativeAd?.setAdUnitID(self.adUnitID) + self.nativeAd?.setTemplateRenderSize(adSize) + self.nativeAd?.delegate = self + self.nativeAd?.loadAd() +#endif + } + + func show() { +#if canImport(TradPlusAds) + guard self.isReady else { return } + guard let adView = adView else { return } +// let view = FATradPlusNativeAdView() +// +// let nativeRenderer = TradPlusNativeRenderer() +// nativeRenderer.setTitleLable(view.titleLabel, canClick: true) + +// self.nativeAd?.showAD(with: nativeRenderer, subview: adView, sceneId: nil) + self.nativeAd?.showAD(withRenderingViewClass: FATradPlusNativeAdView.self, subview: adView, sceneId: nil) +#endif + + } + + +} + +//MARK: TradPlusADNativeDelegate +#if canImport(TradPlusAds) +extension FATradPlusNativeAd: TradPlusADNativeDelegate { + + func tpNativeAdLoaded(_ adInfo: [AnyHashable : Any]) { + self.delegate?.fa_nativeAdDidLoadFinish(nativeAd: self) + } + + func tpNativeAdImpression(_ adInfo: [AnyHashable : Any]) { + self.delegate?.fa_nativeAdDidShow(nativeAd: self) + } + + func tpNativeAdLoadFailWithError(_ error: any Error) { + self.delegate?.fa_nativeAd(nativeAd: self, didLoadFail: error) + } + + func tpNativeAdShow(_ adInfo: [AnyHashable : Any], didFailWithError error: any Error) { + self.delegate?.fa_nativeAd(nativeAd: self, didDisplayFail: error) + } + + func tpNativeAdClicked(_ adInfo: [AnyHashable : Any]) { + self.delegate?.fa_nativeAdDidClick(nativeAd: self) + } + + func tpNativeAdClose(_ adInfo: [AnyHashable : Any]) { + self.delegate?.fa_nativeAdDidDismiss(nativeAd: self) + } + +} +#endif diff --git a/Fableon/Object/Libs/AdManager/Native/FATradPlusNativeAdView.swift b/Fableon/Object/Libs/AdManager/Native/FATradPlusNativeAdView.swift new file mode 100644 index 0000000..651ef09 --- /dev/null +++ b/Fableon/Object/Libs/AdManager/Native/FATradPlusNativeAdView.swift @@ -0,0 +1,160 @@ +// +// FATradPlusNativeAdView.swift +// Fableon +// +// Created by 湖北秦九 on 2026/1/29. +// + +import UIKit +import SnapKit +#if canImport(TradPlusAds) +import TradPlusAds +#endif + +class FATradPlusNativeAdView: UIView { + + + lazy var mainImageView: FAImageView = { + let imageView = FAImageView() + return imageView + }() + + lazy var iconImageView: UIImageView = { + let imageView = FAImageView() + imageView.layer.cornerRadius = 5 + imageView.layer.masksToBounds = true + return imageView + }() + + lazy var titleLabel: UILabel = { + let label = UILabel() + label.textColor = .black + label.textAlignment = .center + label.numberOfLines = 0 + return label + }() + + lazy var textLabel: UILabel = { + let label = UILabel() + label.textColor = .black + label.textAlignment = .center + label.numberOfLines = 0 + return label + }() + + lazy var ctaLabel: UILabel = { + let label = UILabel() + label.textColor = .white + label.textAlignment = .center + label.numberOfLines = 0 + label.layer.cornerRadius = 5 + label.layer.masksToBounds = true + label.backgroundColor = .CC_3333 + return label + }() + + lazy var adChoiceImageView: UIImageView = { + let imageView = UIImageView() + return imageView + }() + + lazy var adLabel: UILabel = { + let label = UILabel() + label.textColor = .orange + label.font = .font(ofSize: 10, weight: .regular) + label.text = "AD" + return label + }() + + override init(frame: CGRect) { + super.init(frame: frame) + self.backgroundColor = .white + fa_layoutUI() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func fa_layoutUI() { + addSubview(mainImageView) + addSubview(iconImageView) + addSubview(titleLabel) + addSubview(textLabel) + addSubview(ctaLabel) + addSubview(adChoiceImageView) + addSubview(adLabel) + + mainImageView.snp.makeConstraints { make in + make.left.right.top.equalToSuperview() +// make.height.equalTo(80) + make.height.equalTo(mainImageView.snp.width).multipliedBy(0.5) + } + + iconImageView.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.top.equalTo(mainImageView.snp.bottom).offset(10) + make.width.height.equalTo(50) + } + + titleLabel.snp.makeConstraints { make in + make.top.equalTo(iconImageView.snp.bottom).offset(10) + make.centerX.equalToSuperview() + make.right.lessThanOrEqualToSuperview().offset(-10) + } + + textLabel.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.top.equalTo(titleLabel.snp.bottom).offset(10) + make.right.lessThanOrEqualToSuperview().offset(-10) + } + + ctaLabel.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.top.equalTo(textLabel.snp.bottom).offset(10) + make.right.equalToSuperview().offset(-10) + make.height.equalTo(40) + } + + adChoiceImageView.snp.makeConstraints { make in + make.width.height.equalTo(10) + make.right.equalToSuperview().offset(-10) + make.bottom.equalToSuperview().offset(-10) + } + + adLabel.snp.makeConstraints { make in + make.left.equalToSuperview().offset(10) + make.centerY.equalTo(adChoiceImageView) + } + } + +} + +#if canImport(TradPlusAds) +extension FATradPlusNativeAdView: TradPlusNativeAdRendering { + + func nativeTitleTextLabel() -> UILabel! { + return titleLabel + } + + func nativeMainTextLabel() -> UILabel! { + return textLabel + } + + func nativeIconImageView() -> UIImageView! { + return iconImageView + } + + func nativeMainImageView() -> UIImageView! { + return mainImageView + } + + func nativeCallToActionTextLabel() -> UILabel! { + return ctaLabel + } + + func nativePrivacyInformationIconImageView() -> UIImageView! { + return adChoiceImageView + } +} +#endif diff --git a/Fableon/Object/Libs/AdManager/Open/FAOpenAdManager.swift b/Fableon/Object/Libs/AdManager/Open/FAOpenAdManager.swift new file mode 100644 index 0000000..b9db6b3 --- /dev/null +++ b/Fableon/Object/Libs/AdManager/Open/FAOpenAdManager.swift @@ -0,0 +1,234 @@ +// +// FAOpenAdManager.swift +// Fableon +// +// Created by 湖北秦九 on 2026/1/23. +// + +import UIKit + +@objc protocol FAOpenAdManagerDelegate: NSObjectProtocol { + /// 广告加载失败 + @objc optional func fa_openAdManager(manager: FAOpenAdManager, didLoadFail error: Error) + /// 广告加载成功 + @objc optional func fa_openAdManagerDidLoadFinish(manager: FAOpenAdManager) + /// 广告展示失败 + @objc optional func fa_openAdManager(manager: FAOpenAdManager, didDisplayFail error: Error) + /// 广告被展示 + @objc optional func fa_openAdManagerDidShow(manager: FAOpenAdManager) + /// 广告被关闭 + @objc optional func fa_openAdManagerDidDismiss(manager: FAOpenAdManager) + /// 其它错误 + @objc optional func fa_openAdManager(manager: FAOpenAdManager, didOtherFail error: Error) +} + +protocol FAOpenAdDelegate: NSObjectProtocol { + func fa_openAd(ad: FAOpenAd, didLoadFail error: Error) + func fa_openAdDidLoadFinish(ad: FAOpenAd) + func fa_openAd(ad: FAOpenAd, didDisplayFail error: Error) + func fa_openAdDidShow(ad: FAOpenAd) + func fa_openAdDidDismiss(ad: FAOpenAd) + func fa_openAdDidClick(ad: FAOpenAd) +} + +protocol FAOpenAd: NSObjectProtocol { + var delegate: FAOpenAdDelegate? { get set } + var adPlatform: FAAdPlatform { get } + var adType: FAAdType { get } + var adUnitID: String { get } + var isReady: Bool { get } + + func loadAd() + func showAd() +} + +class FAOpenAdManager: NSObject { + + static let manager = FAOpenAdManager() + + weak var delegate: FAOpenAdManagerDelegate? + + var openAdVC: FAOpenViewController = FAOpenViewController() + + private var appOpenAd: FAOpenAd? { + didSet { + oldValue?.delegate = nil + appOpenAd?.delegate = self + } + } + + ///控制当前页面是否可以展示广告,冷启动有效 + var vcAllowedShowAd = true + ///广告是否在加载中 + private(set) var isLoadingAd = false + ///广告正在被展示 + private(set) var isShowingAd = false + /// 标记是否在等待广告加载完成后自动展示 + private(set) var isWaitingToShow = false + private var timeOutTimer: Timer? + + var isAdAvailable: Bool { + return appOpenAd?.isReady ?? false + } + + deinit { + NotificationCenter.default.removeObserver(self) + } + + private override init() { + super.init() + NotificationCenter.default.addObserver(self, selector: #selector(didEnterBackgroundNotification), name: UIApplication.didEnterBackgroundNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActiveNotification), name: UIApplication.didBecomeActiveNotification, object: nil) + } + + func loadAd() { + if isLoadingAd || isAdAvailable { + return + } + isLoadingAd = true + + appOpenAd = FATradPlusOpenAd() + appOpenAd?.loadAd() + } + + func showAd() { + guard let ad = appOpenAd, isAdAvailable else { + loadAd() + return + } + if self.openAdVC.view.isHidden { return } + + isWaitingToShow = false + isShowingAd = true + ad.showAd() + } + + /// 外部调用的主要入口 + func showAdIfAvailable() { + // 如果正在展示广告,不再重复触发 + guard !isShowingAd else { return } + + // 1. 如果广告已就绪,直接展示 + if isAdAvailable { + showAd() + return + } + + // 2. 如果没有就绪,标记等待并开始加载,同时开启超时保护 + isWaitingToShow = true + startTimeoutTimer() + loadAd() + } + + + + // MARK: - Timer (防止加载时间过长,用户已进入首页后突然弹出广告) + private func startTimeoutTimer() { + clearTimer() + timeOutTimer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false) { [weak self] _ in + Task { @MainActor in + self?.handleTimeOut() + } + } + } + + @objc private func handleTimeOut() { + if isWaitingToShow { + isWaitingToShow = false + let error = NSError(domain: "time-out", code: -1) + delegate?.fa_openAdManager?(manager: self, didOtherFail: error) + } + clearTimer() + } + + private func clearTimer() { + timeOutTimer?.invalidate() + timeOutTimer = nil + } + + + +} + +// MARK: - BRAppOpenAdDelegate +extension FAOpenAdManager: FAOpenAdDelegate { + + func fa_openAd(ad: FAOpenAd, didLoadFail error: Error) { + isLoadingAd = false + isWaitingToShow = false + appOpenAd = nil + clearTimer() + requestStatAd(type: "load_failed", errorMsg: error.localizedDescription) + delegate?.fa_openAdManager?(manager: self, didLoadFail: error) + } + + func fa_openAdDidLoadFinish(ad: FAOpenAd) { + isLoadingAd = false + delegate?.fa_openAdManagerDidLoadFinish?(manager: self) + + // 如果之前处于等待展示状态,现在立即展示 + if isWaitingToShow { + clearTimer() + showAd() + } + } + + func fa_openAd(ad: FAOpenAd, didDisplayFail error: Error) { + isShowingAd = false + isWaitingToShow = false + appOpenAd = nil + clearTimer() + requestStatAd(type: "show_failed", errorMsg: error.localizedDescription) + delegate?.fa_openAdManager?(manager: self, didDisplayFail: error) + } + + func fa_openAdDidShow(ad: FAOpenAd) { + requestStatAd(type: "start", errorMsg: nil) + delegate?.fa_openAdManagerDidShow?(manager: self) + } + + func fa_openAdDidDismiss(ad: FAOpenAd) { + isShowingAd = false + appOpenAd = nil + delegate?.fa_openAdManagerDidDismiss?(manager: self) + // 关闭后自动预加载下一条,5秒后开始加载 + DispatchQueue.main.asyncAfter(deadline: .now() + 10) { [weak self] in + guard let self = self else { return } + self.loadAd() + } + } + + func fa_openAdDidClick(ad: FAOpenAd) { + requestStatAd(type: "click", errorMsg: nil) + } +} + +// MARK: - Statistics +extension FAOpenAdManager { + private func requestStatAd(type: String, errorMsg: String?) { + guard let appOpenAd = appOpenAd else { return } + + // let model = SPStatAdModel() + // model.type = type + // model.ads_id = appOpenAd.adUnitID + // model.ad_platform_key = SPAdPlatformKey(rawValue: appOpenAd.adPlatformKey) + // model.error_msg = errorMsg + // model.scene = .splash + // + // SPStatAPI.requestStatAd(model: model) + } + + + @objc private func didEnterBackgroundNotification() { + if !self.isShowingAd { return } + + self.requestStatAd(type: "Interrupt", errorMsg: nil) + } + + @objc private func didBecomeActiveNotification() { + if self.isAdAvailable, self.vcAllowedShowAd { + self.openAdVC.view.isHidden = false + self.showAd() + } + } +} diff --git a/Fableon/Object/Libs/AdManager/Open/FAOpenViewController.swift b/Fableon/Object/Libs/AdManager/Open/FAOpenViewController.swift new file mode 100644 index 0000000..2f485b0 --- /dev/null +++ b/Fableon/Object/Libs/AdManager/Open/FAOpenViewController.swift @@ -0,0 +1,57 @@ +// +// FAOpenViewController.swift +// Fableon +// +// Created by 湖北秦九 on 2026/1/24. +// + +import UIKit + +class FAOpenViewController: UIViewController { + + private lazy var lanuchVC: UIViewController? = { + return FATool.getLanuchViewController() + }() + + override func viewDidLoad() { + super.viewDidLoad() + if let vc = lanuchVC { + addChild(vc) + view.addSubview(vc.view) + } + + FAOpenAdManager.manager.delegate = self + + } + + + +} + +//MARK: FAOpenAdManagerDelegate +extension FAOpenViewController: FAOpenAdManagerDelegate { + + func fa_openAdManagerDidShow(manager: FAOpenAdManager) { + + } + + func fa_openAdManagerDidDismiss(manager: FAOpenAdManager) { + self.view.isHidden = true + } + + func fa_openAdManager(manager: FAOpenAdManager, didLoadFail error: any Error) { + self.view.isHidden = true + } + + func fa_openAdManager(manager: FAOpenAdManager, didOtherFail error: any Error) { + self.view.isHidden = true + } + + func fa_openAdManager(manager: FAOpenAdManager, didDisplayFail error: any Error) { + self.view.isHidden = true + } + + + + +} diff --git a/Fableon/Object/Libs/AdManager/Open/FATradPlusOpenAd.swift b/Fableon/Object/Libs/AdManager/Open/FATradPlusOpenAd.swift new file mode 100644 index 0000000..4d54fac --- /dev/null +++ b/Fableon/Object/Libs/AdManager/Open/FATradPlusOpenAd.swift @@ -0,0 +1,108 @@ +// +// BRTradPlusOpenAd.swift +// Fableon +// +// Created by 湖北秦九 on 2026/1/23. +// + +import UIKit +#if canImport(TradPlusAds) +import TradPlusAds +#endif + +class FATradPlusOpenAd: NSObject, FAOpenAd { + +#if canImport(TradPlusAds) + private var appOpenAd: TradPlusAdSplash? +#endif + + weak var delegate: FAOpenAdDelegate? + + var adPlatform: FAAdPlatform { + return .tradPlus + } + + var adType: FAAdType { + return .open + } + + var adUnitID: String { + return self.adPlatform.openUnitId + } + + var isReady: Bool { +#if canImport(TradPlusAds) + return self.appOpenAd?.isAdReady ?? false +#else + return false +#endif + } + + func loadAd() { +#if canImport(TradPlusAds) + appOpenAd = nil + + guard let targetWindow = FATool.keyWindow else { + let error = NSError(domain: "com.beereel.ad", + code: -2, + userInfo: [NSLocalizedDescriptionKey: "TradPlus failed: No active window found"]) + self.delegate?.fa_openAd(ad: self, didLoadFail: error) + return + } + // 3. 初始化并配置 + let splash = TradPlusAdSplash() + splash.setAdUnitID(adUnitID) + splash.delegate = self + self.appOpenAd = splash + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { + splash.loadAd(with: targetWindow, bottomView: nil) + } +#endif + } + + func showAd() { + if isReady { +#if canImport(TradPlusAds) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in + guard let self = self else { return } + self.appOpenAd?.show() + } +#endif + } + } + +} + +#if canImport(TradPlusAds) +// MARK: - TradPlusADSplashDelegate +extension FATradPlusOpenAd: TradPlusADSplashDelegate { + + func tpSplashAdLoaded(_ adInfo: [AnyHashable : Any]) { + self.delegate?.fa_openAdDidLoadFinish(ad: self) + } + + func tpSplashAdLoadFailWithError(_ error: Error, adInfo: [AnyHashable : Any]) { + self.appOpenAd = nil + self.delegate?.fa_openAd(ad: self, didLoadFail: error) + } + + func tpSplashAdImpression(_ adInfo: [AnyHashable : Any]) { + self.delegate?.fa_openAdDidShow(ad: self) + } + + func tpSplashAdShow(_ adInfo: [AnyHashable : Any], didFailWithError error: Error) { + self.appOpenAd = nil + self.delegate?.fa_openAd(ad: self, didDisplayFail: error) + } + + func tpSplashAdClicked(_ adInfo: [AnyHashable : Any]) { + self.delegate?.fa_openAdDidClick(ad: self) + } + + func tpSplashAdDismissed(_ adInfo: [AnyHashable : Any]) { + self.appOpenAd = nil + self.delegate?.fa_openAdDidDismiss(ad: self) + } +} +#endif diff --git a/Fableon/Object/Libs/AdManager/Rewarded/FARewardedAdInfo.swift b/Fableon/Object/Libs/AdManager/Rewarded/FARewardedAdInfo.swift new file mode 100644 index 0000000..b77b566 --- /dev/null +++ b/Fableon/Object/Libs/AdManager/Rewarded/FARewardedAdInfo.swift @@ -0,0 +1,27 @@ +// +// FARewardedAdInfo.swift +// Fableon +// +// Created by 湖北秦九 on 2026/1/26. +// + +import UIKit +import SmartCodable + +class FARewardedAdData: NSObject, SmartCodable { + + required override init() { } + + var ad: FARewardedAdInfo? +} + +class FARewardedAdInfo: NSObject, SmartCodable { + + required override init() { } + + var id: String? + var platform_name: String? + var ads_id: String? + var status: String? + var platform_key: FAAdPlatform? +} diff --git a/Fableon/Object/Libs/AdManager/Rewarded/FARewardedAdManager.swift b/Fableon/Object/Libs/AdManager/Rewarded/FARewardedAdManager.swift new file mode 100644 index 0000000..59d84ff --- /dev/null +++ b/Fableon/Object/Libs/AdManager/Rewarded/FARewardedAdManager.swift @@ -0,0 +1,157 @@ +// +// FARewardedAdManager.swift +// Fableon +// +// Created by 湖北秦九 on 2026/1/24. +// + +import UIKit + +@objc protocol FARewardedAdManagerDelegate: NSObjectProtocol { + + ///发放奖励 +// @objc optional func rewardedAdManager(adManager: BRRewardedAdManager, userDidEarnReward adInfo: VPAdInfo) + ///广告加载成功 + @objc optional func fa_rewardedAdManagerDidLoadFinish(adManager: FARewardedAdManager) + ///广告加载失败 + @objc optional func fa_rewardedAdManager(adManager: FARewardedAdManager, didLoadFail error: Error) + ///广告展示失败 + @objc optional func fa_rewardedAdManager(adManager: FARewardedAdManager, didDisplayFail error: Error) + ///广告被展示 + @objc optional func fa_rewardedAdManagerDidShow(adManager: FARewardedAdManager) + ///广告被关闭 + @objc optional func fa_rewardedAdManagerDidDismiss(adManager: FARewardedAdManager) + ///广告被点击 + @objc optional func fa_rewardedAdManagerDidClick(adManager: FARewardedAdManager) + ///其它错误 + @objc optional func fa_rewardedAdManager(adManager: FARewardedAdManager, didOtherFail error: Error) + +} + +protocol FARewardedAdDelegate: NSObjectProtocol { + + ///发放奖励 +// func rewardedAd(ad: BRRewardedAd, userDidEarnReward adInfo: VPAdInfo) + ///广告加载失败 + func fa_rewardedAd(ad: FARewardedAd, didLoadFail error: Error) + ///广告加载成功 + func fa_rewardedAdDidLoadFinish(ad: FARewardedAd) + ///广告展示失败 + func fa_rewardedAd(ad: FARewardedAd, didDisplayFail error: Error) + ///广告被展示 + func fa_rewardedAdDidShow(ad: FARewardedAd) + ///广告被关闭 + func fa_rewardedAdDidDismiss(ad: FARewardedAd) + ///广告被点击 + func fa_rewardedAdDidClick(ad: FARewardedAd) +} + +protocol FARewardedAd: NSObjectProtocol { + + var delegate: FARewardedAdDelegate? { get set } + var adPlatform: FAAdPlatform { get } + var adType: FAAdType { get } + var adUnitID: String { get } + var networkName: String { get set } + var isReady: Bool { get } + + func loadAd() + func showAd() + +} + +class FARewardedAdManager: NSObject { + + static let manager = FARewardedAdManager() + + weak var delegate: FARewardedAdManagerDelegate? + + var rewardedAd: FARewardedAd? { + didSet { + oldValue?.delegate = nil + rewardedAd?.delegate = self + } + } + + var isAdAvailable: Bool { + return rewardedAd?.isReady ?? false + } + + + + + override init() { + super.init() + } + + func load() { + if self.isAdAvailable { return } + +// if loadAdType != .rewarded { +// loadAdType = .rewarded +// } else { +// loadAdType = .interstitial +// } +// +// if loadAdType == .rewarded { +// self.rewardedAd = FATradPlusRewardedAd() +// } else { + self.rewardedAd = FATradPlusInterstitialAd() +// } + self.rewardedAd?.loadAd() + +// self.requestAdOverview() + } + + func show() { + guard self.isAdAvailable else { return } + + self.rewardedAd?.showAd() + } + + +} + +//MARK: FARewardedAdDelegate +extension FARewardedAdManager: FARewardedAdDelegate { + + func fa_rewardedAd(ad: any FARewardedAd, didLoadFail error: any Error) { + self.rewardedAd = nil + self.delegate?.fa_rewardedAdManager?(adManager: self, didLoadFail: error) + } + + func fa_rewardedAd(ad: any FARewardedAd, didDisplayFail error: any Error) { + self.rewardedAd = nil + self.delegate?.fa_rewardedAdManager?(adManager: self, didDisplayFail: error) + } + + func fa_rewardedAdDidLoadFinish(ad: any FARewardedAd) { + self.delegate?.fa_rewardedAdManagerDidLoadFinish?(adManager: self) + } + + func fa_rewardedAdDidShow(ad: any FARewardedAd) { + self.delegate?.fa_rewardedAdManagerDidShow?(adManager: self) + } + + func fa_rewardedAdDidDismiss(ad: any FARewardedAd) { + self.rewardedAd = nil + self.delegate?.fa_rewardedAdManagerDidDismiss?(adManager: self) + //加载新的广告 + self.load() + } + + func fa_rewardedAdDidClick(ad: any FARewardedAd) { + self.delegate?.fa_rewardedAdManagerDidClick?(adManager: self) + } +} + +extension FARewardedAdManager { + + private func requestAdOverview() { + + FAAPI.requestRewardedAdOverview { [weak self] list in + guard let self = self else { return } + + } + } +} diff --git a/Fableon/Object/Libs/AdManager/Rewarded/FARewardedAdOverview.swift b/Fableon/Object/Libs/AdManager/Rewarded/FARewardedAdOverview.swift new file mode 100644 index 0000000..c945d5e --- /dev/null +++ b/Fableon/Object/Libs/AdManager/Rewarded/FARewardedAdOverview.swift @@ -0,0 +1,28 @@ +// +// FARewardedAdOverview.swift +// Fableon +// +// Created by 湖北秦九 on 2026/1/26. +// + +import UIKit +import SmartCodable + +class FARewardedAdOverview: NSObject, SmartCodable { + + required override init() { } + + var id: String? + var platform_key: FAAdPlatform? + var watch_times_limit: Int? + var polling_times: Int? + + var ad_type: FARewardedAdWeight? +} + +class FARewardedAdWeight: NSObject, SmartCodable { + required override init() { } + + var reward: Int? + var interstitial: Int? +} diff --git a/Fableon/Object/Libs/AdManager/Rewarded/FATradPlusInterstitialAd.swift b/Fableon/Object/Libs/AdManager/Rewarded/FATradPlusInterstitialAd.swift new file mode 100644 index 0000000..af099cb --- /dev/null +++ b/Fableon/Object/Libs/AdManager/Rewarded/FATradPlusInterstitialAd.swift @@ -0,0 +1,91 @@ +// +// FATradPlusInterstitialAd.swift +// Fableon +// +// Created by 湖北秦九 on 2026/1/26. +// + +import UIKit +#if canImport(TradPlusAds) +import TradPlusAds +#endif + +class FATradPlusInterstitialAd: NSObject, FARewardedAd { + +#if canImport(TradPlusAds) + private var interstitialAd: TradPlusAdInterstitial? +#endif + + var delegate: FARewardedAdDelegate? + + var adPlatform: FAAdPlatform { + return .tradPlus + } + + var adType: FAAdType { + return .interstitial + } + + var adUnitID: String { + return adPlatform.interstitialUnitId + } + + var networkName: String = "" + + var isReady: Bool { +#if canImport(TradPlusAds) + return self.interstitialAd?.isAdReady ?? false +#else + return false +#endif + } + + func loadAd() { +#if canImport(TradPlusAds) + self.interstitialAd = TradPlusAdInterstitial() + self.interstitialAd?.setAdUnitID(self.adUnitID) + self.interstitialAd?.delegate = self + self.interstitialAd?.loadAd() +#endif + } + + func showAd() { +#if canImport(TradPlusAds) + guard self.isReady else { return } + self.interstitialAd?.showAd(withSceneId: nil) +#endif + } + + +} + +#if canImport(TradPlusAds) +//MARK: TradPlusADInterstitialDelegate +extension FATradPlusInterstitialAd: TradPlusADInterstitialDelegate { + + func tpInterstitialAdLoaded(_ adInfo: [AnyHashable : Any]) { + self.networkName = (adInfo["adNetworkName"] as? String) ?? "unknown" + self.delegate?.fa_rewardedAdDidLoadFinish(ad: self) + } + + func tpInterstitialAdImpression(_ adInfo: [AnyHashable : Any]) { + self.delegate?.fa_rewardedAdDidShow(ad: self) + } + + func tpInterstitialAdLoadFailWithError(_ error: any Error) { + self.delegate?.fa_rewardedAd(ad: self, didLoadFail: error) + } + + func tpInterstitialAdShow(_ adInfo: [AnyHashable : Any], didFailWithError error: any Error) { + self.delegate?.fa_rewardedAd(ad: self, didDisplayFail: error) + } + + func tpInterstitialAdClicked(_ adInfo: [AnyHashable : Any]) { + self.delegate?.fa_rewardedAdDidClick(ad: self) + } + + func tpInterstitialAdDismissed(_ adInfo: [AnyHashable : Any]) { + self.delegate?.fa_rewardedAdDidDismiss(ad: self) + } +} +#endif diff --git a/Fableon/Object/Libs/AdManager/Rewarded/FATradPlusRewardedAd.swift b/Fableon/Object/Libs/AdManager/Rewarded/FATradPlusRewardedAd.swift new file mode 100644 index 0000000..a9d4240 --- /dev/null +++ b/Fableon/Object/Libs/AdManager/Rewarded/FATradPlusRewardedAd.swift @@ -0,0 +1,90 @@ +// +// FATradPlusRewardedAd.swift +// Fableon +// +// Created by 湖北秦九 on 2026/1/24. +// + +import UIKit +#if canImport(TradPlusAds) +import TradPlusAds +#endif + +class FATradPlusRewardedAd: NSObject, FARewardedAd { + +#if canImport(TradPlusAds) + private var rewardedAd: TradPlusAdRewarded? +#endif + + weak var delegate: FARewardedAdDelegate? + + var adPlatform: FAAdPlatform = .tradPlus + + var adType: FAAdType { + return .rewarded + } + + var adUnitID: String { + return self.adPlatform.rewardedUnitId + } + + var networkName: String = "" + + var isReady: Bool { +#if canImport(TradPlusAds) + return self.rewardedAd?.isAdReady ?? false +#else + return false +#endif + } + + func loadAd() { +#if canImport(TradPlusAds) + rewardedAd = TradPlusAdRewarded() + rewardedAd?.setAdUnitID(self.adUnitID) + rewardedAd?.delegate = self + rewardedAd?.loadAd() +#endif + } + + func showAd() { +#if canImport(TradPlusAds) + guard isReady else { return } + self.rewardedAd?.showAd(withSceneId: nil) +#endif + } + +} +#if canImport(TradPlusAds) +extension FATradPlusRewardedAd: TradPlusADRewardedDelegate { + + func tpRewardedAdLoaded(_ adInfo: [AnyHashable : Any]) { + self.networkName = (adInfo["adNetworkName"] as? String) ?? "unknown" + self.delegate?.fa_rewardedAdDidLoadFinish(ad: self) + } + + func tpRewardedAdLoadFailWithError(_ error: any Error) { + self.delegate?.fa_rewardedAd(ad: self, didLoadFail: error) + } + + func tpRewardedAdImpression(_ adInfo: [AnyHashable : Any]) { + self.delegate?.fa_rewardedAdDidShow(ad: self) + } + + func tpRewardedAdShow(_ adInfo: [AnyHashable : Any], didFailWithError error: any Error) { + self.delegate?.fa_rewardedAd(ad: self, didDisplayFail: error) + } + + func tpRewardedAdClicked(_ adInfo: [AnyHashable : Any]) { + self.delegate?.fa_rewardedAdDidClick(ad: self) + } + + func tpRewardedAdDismissed(_ adInfo: [AnyHashable : Any]) { + self.delegate?.fa_rewardedAdDidDismiss(ad: self) + } + + func tpRewardedAdReward(_ adInfo: [AnyHashable : Any]) { + // self.delegate?.fa_rewardedAdDidShow(ad: <#T##any BRRewardedAd#>) + } +} +#endif diff --git a/Fableon/Object/Libs/Alert/FAPayRetainAlert.swift b/Fableon/Object/Libs/Alert/FAPayRetainAlert.swift index 39239eb..56b7875 100644 --- a/Fableon/Object/Libs/Alert/FAPayRetainAlert.swift +++ b/Fableon/Object/Libs/Alert/FAPayRetainAlert.swift @@ -12,6 +12,8 @@ import YYText class FAPayRetainAlert: FABaseAlert { var buyFinishHandle: (() -> Void)? + + var didDismissHandle: (() -> Void)? var model: FAPayDateModel? { didSet { @@ -93,6 +95,11 @@ class FAPayRetainAlert: FABaseAlert { @MainActor required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + override func dismiss() { + super.dismiss() + self.didDismissHandle?() + } } diff --git a/Fableon/Source/Assets.xcassets/color/#CC3333.colorset/Contents.json b/Fableon/Source/Assets.xcassets/color/#CC3333.colorset/Contents.json new file mode 100644 index 0000000..9453bc6 --- /dev/null +++ b/Fableon/Source/Assets.xcassets/color/#CC3333.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x33", + "green" : "0x33", + "red" : "0xCC" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Fableon/Source/Assets.xcassets/image/Frame 3030.imageset/Contents.json b/Fableon/Source/Assets.xcassets/image/Frame 3030.imageset/Contents.json index 886807c..7a6345f 100644 --- a/Fableon/Source/Assets.xcassets/image/Frame 3030.imageset/Contents.json +++ b/Fableon/Source/Assets.xcassets/image/Frame 3030.imageset/Contents.json @@ -7,11 +7,33 @@ { "filename" : "Frame 3030@2x.png", "idiom" : "universal", + "resizing" : { + "cap-insets" : { + "left" : 37, + "right" : 35 + }, + "center" : { + "mode" : "tile", + "width" : 1 + }, + "mode" : "3-part-horizontal" + }, "scale" : "2x" }, { "filename" : "Frame 3030@3x.png", "idiom" : "universal", + "resizing" : { + "cap-insets" : { + "left" : 44, + "right" : 49 + }, + "center" : { + "mode" : "tile", + "width" : 1 + }, + "mode" : "3-part-horizontal" + }, "scale" : "3x" } ], diff --git a/Fableon/Source/Assets.xcassets/image/Rectangle 36.imageset/Contents.json b/Fableon/Source/Assets.xcassets/image/Rectangle 36.imageset/Contents.json index c2a4324..1d3d315 100644 --- a/Fableon/Source/Assets.xcassets/image/Rectangle 36.imageset/Contents.json +++ b/Fableon/Source/Assets.xcassets/image/Rectangle 36.imageset/Contents.json @@ -9,8 +9,8 @@ "idiom" : "universal", "resizing" : { "cap-insets" : { - "left" : 27, - "right" : 24 + "left" : 24, + "right" : 23 }, "center" : { "mode" : "tile", @@ -25,8 +25,8 @@ "idiom" : "universal", "resizing" : { "cap-insets" : { - "left" : 31, - "right" : 35 + "left" : 33, + "right" : 37 }, "center" : { "mode" : "tile", diff --git a/Fableon/Source/Assets.xcassets/image/Rectangle 36.imageset/Rectangle 36@2x.png b/Fableon/Source/Assets.xcassets/image/Rectangle 36.imageset/Rectangle 36@2x.png index cafe86b..7f4ab0d 100644 Binary files a/Fableon/Source/Assets.xcassets/image/Rectangle 36.imageset/Rectangle 36@2x.png and b/Fableon/Source/Assets.xcassets/image/Rectangle 36.imageset/Rectangle 36@2x.png differ diff --git a/Fableon/Source/Assets.xcassets/image/Rectangle 36.imageset/Rectangle 36@3x.png b/Fableon/Source/Assets.xcassets/image/Rectangle 36.imageset/Rectangle 36@3x.png index 54ebdca..90c2a8d 100644 Binary files a/Fableon/Source/Assets.xcassets/image/Rectangle 36.imageset/Rectangle 36@3x.png and b/Fableon/Source/Assets.xcassets/image/Rectangle 36.imageset/Rectangle 36@3x.png differ diff --git a/Fableon/Source/Assets.xcassets/image/Rectangle 6216.imageset/Contents.json b/Fableon/Source/Assets.xcassets/image/Rectangle 6216.imageset/Contents.json index 3e5b274..bd409d5 100644 --- a/Fableon/Source/Assets.xcassets/image/Rectangle 6216.imageset/Contents.json +++ b/Fableon/Source/Assets.xcassets/image/Rectangle 6216.imageset/Contents.json @@ -7,11 +7,33 @@ { "filename" : "Rectangle 6216@2x.png", "idiom" : "universal", + "resizing" : { + "cap-insets" : { + "left" : 74, + "right" : 65 + }, + "center" : { + "mode" : "tile", + "width" : 1 + }, + "mode" : "3-part-horizontal" + }, "scale" : "2x" }, { "filename" : "Rectangle 6216@3x.png", "idiom" : "universal", + "resizing" : { + "cap-insets" : { + "left" : 83, + "right" : 91 + }, + "center" : { + "mode" : "tile", + "width" : 1 + }, + "mode" : "3-part-horizontal" + }, "scale" : "3x" } ], diff --git a/Fableon/Source/Assets.xcassets/image/Rectangle 6216.imageset/Rectangle 6216@2x.png b/Fableon/Source/Assets.xcassets/image/Rectangle 6216.imageset/Rectangle 6216@2x.png index 5782c22..b54508c 100644 Binary files a/Fableon/Source/Assets.xcassets/image/Rectangle 6216.imageset/Rectangle 6216@2x.png and b/Fableon/Source/Assets.xcassets/image/Rectangle 6216.imageset/Rectangle 6216@2x.png differ diff --git a/Fableon/Source/Assets.xcassets/image/Rectangle 6216.imageset/Rectangle 6216@3x.png b/Fableon/Source/Assets.xcassets/image/Rectangle 6216.imageset/Rectangle 6216@3x.png index 0a4900c..55a9446 100644 Binary files a/Fableon/Source/Assets.xcassets/image/Rectangle 6216.imageset/Rectangle 6216@3x.png and b/Fableon/Source/Assets.xcassets/image/Rectangle 6216.imageset/Rectangle 6216@3x.png differ diff --git a/Fableon/Source/Info.plist b/Fableon/Source/Info.plist index 0fa6392..8a73d4a 100755 --- a/Fableon/Source/Info.plist +++ b/Fableon/Source/Info.plist @@ -2,6 +2,8 @@ + GADApplicationIdentifier + ca-app-pub-3940256099942544~1458002511 CFBundleURLTypes @@ -21,6 +23,11 @@ + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + FacebookAppID 1309643747870828 FacebookClientToken @@ -53,5 +60,204 @@ UIDesignRequiresCompatibility + SKAdNetworkItems + + + SKAdNetworkIdentifier + cstr6suwn9.skadnetwork + + + SKAdNetworkIdentifier + 4fzdc2evr5.skadnetwork + + + SKAdNetworkIdentifier + 2fnua5tdw4.skadnetwork + + + SKAdNetworkIdentifier + ydx93a7ass.skadnetwork + + + SKAdNetworkIdentifier + p78axxw29g.skadnetwork + + + SKAdNetworkIdentifier + v72qych5uu.skadnetwork + + + SKAdNetworkIdentifier + ludvb6z3bs.skadnetwork + + + SKAdNetworkIdentifier + cp8zw746q7.skadnetwork + + + SKAdNetworkIdentifier + 3sh42y64q3.skadnetwork + + + SKAdNetworkIdentifier + c6k4g5qg8m.skadnetwork + + + SKAdNetworkIdentifier + s39g8k73mm.skadnetwork + + + SKAdNetworkIdentifier + 3qy4746246.skadnetwork + + + SKAdNetworkIdentifier + f38h382jlk.skadnetwork + + + SKAdNetworkIdentifier + hs6bdukanm.skadnetwork + + + SKAdNetworkIdentifier + mlmmfzh3r3.skadnetwork + + + SKAdNetworkIdentifier + v4nxqhlyqp.skadnetwork + + + SKAdNetworkIdentifier + wzmmz9fp6w.skadnetwork + + + SKAdNetworkIdentifier + su67r6k2v3.skadnetwork + + + SKAdNetworkIdentifier + yclnxrl5pm.skadnetwork + + + SKAdNetworkIdentifier + t38b2kh725.skadnetwork + + + SKAdNetworkIdentifier + 7ug5zh24hu.skadnetwork + + + SKAdNetworkIdentifier + gta9lk7p23.skadnetwork + + + SKAdNetworkIdentifier + vutu7akeur.skadnetwork + + + SKAdNetworkIdentifier + y5ghdn5j9k.skadnetwork + + + SKAdNetworkIdentifier + v9wttpbfk9.skadnetwork + + + SKAdNetworkIdentifier + n38lu8286q.skadnetwork + + + SKAdNetworkIdentifier + 47vhws6wlr.skadnetwork + + + SKAdNetworkIdentifier + kbd757ywx3.skadnetwork + + + SKAdNetworkIdentifier + 9t245vhmpl.skadnetwork + + + SKAdNetworkIdentifier + a2p9lx4jpn.skadnetwork + + + SKAdNetworkIdentifier + 22mmun2rn5.skadnetwork + + + SKAdNetworkIdentifier + 44jx6755aq.skadnetwork + + + SKAdNetworkIdentifier + k674qkevps.skadnetwork + + + SKAdNetworkIdentifier + 4468km3ulz.skadnetwork + + + SKAdNetworkIdentifier + 2u9pt9hc89.skadnetwork + + + SKAdNetworkIdentifier + 8s468mfl3y.skadnetwork + + + SKAdNetworkIdentifier + klf5c3l5u5.skadnetwork + + + SKAdNetworkIdentifier + ppxm28t8ap.skadnetwork + + + SKAdNetworkIdentifier + kbmxgpxpgc.skadnetwork + + + SKAdNetworkIdentifier + uw77j35x4d.skadnetwork + + + SKAdNetworkIdentifier + 578prtvx9j.skadnetwork + + + SKAdNetworkIdentifier + 4dzt52r2t5.skadnetwork + + + SKAdNetworkIdentifier + tl55sbb4fm.skadnetwork + + + SKAdNetworkIdentifier + c3frkrj4fj.skadnetwork + + + SKAdNetworkIdentifier + e5fvkxwrpn.skadnetwork + + + SKAdNetworkIdentifier + 8c4e2ghe7u.skadnetwork + + + SKAdNetworkIdentifier + 3rd42ekr43.skadnetwork + + + SKAdNetworkIdentifier + 97r2b46745.skadnetwork + + + SKAdNetworkIdentifier + 3qcr597p9d.skadnetwork + + diff --git a/Podfile b/Podfile index d7c6b9e..f88a594 100755 --- a/Podfile +++ b/Podfile @@ -1,16 +1,16 @@ -platform :ios, '13.0' +platform :ios, '15.0' source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git' post_install do |installer| installer.pods_project.targets.each do |target| - target.build_configurations.each do |config| - config.build_settings['ENABLE_BITCODE'] = 'NO' - config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64" - config.build_settings['EXCLUDED_ARCHITECTURES'] = 'i386' - config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' - end - end + target.build_configurations.each do |config| + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.0' + config.build_settings.delete('EXCLUDED_ARCHS[sdk=iphonesimulator*]') + config.build_settings.delete('EXCLUDED_ARCHITECTURES') + config.build_settings['ENABLE_BITCODE'] = 'NO' + end + end end target 'Fableon' do @@ -36,5 +36,34 @@ target 'Fableon' do pod 'JXPagingView/Paging' pod 'JXSegmentedView' pod 'Adjust' + +# 广告SDK AdMob Meta Pangle Liftoff Mintegral InMobi Verve Bigo TaurusX UnityAds AppLovin IronSource +# pod 'TradPlusAdSDK', '14.9.0' +# pod 'TradPlusAdSDK/FacebookAdapter', '14.9.0' +# pod 'FBAudienceNetwork','6.20.1' +# pod 'TradPlusAdSDK/AdMobAdapter', '14.9.0' +# pod 'Google-Mobile-Ads-SDK','12.14.0' +# pod 'TradPlusAdSDK/UnityAdapter', '14.9.0' +# pod 'UnityAds','4.16.4' +# pod 'TradPlusAdSDK/AppLovinAdapter', '14.9.0' +# pod 'AppLovinSDK','13.5.0' +# pod 'TradPlusAdSDK/VungleAdapter', '14.9.0' +# pod 'VungleAds', '7.6.1' +# pod 'TradPlusAdSDK/IronSourceAdapter', '14.9.0' +# pod 'IronSourceSDK','9.2.0' +# pod 'TradPlusAdSDK/InMobiAdapter', '14.9.0' +# pod 'InMobiSDK' ,'11.1.0' +# pod 'TradPlusAdSDK/MintegralAdapter', '14.9.0' +# pod 'MintegralAdSDK' ,'7.7.9' +# pod 'MintegralAdSDK/All','7.7.9' +# pod 'TradPlusAdSDK/PangleAdapter', '14.9.0' +# pod 'Ads-Global', '7.8.0.5' +# pod 'TradPlusAdSDK/TPCrossAdapter', '14.9.0' +# pod 'TradPlusAdSDK/VerveAdapter', '14.9.0' +# pod 'HyBid','3.7.1' +# pod 'TradPlusAdSDK/BigoAdapter', '14.9.0' +# pod 'BigoADS','5.0.0' +# pod 'TradPlusAdSDK/TaurusXAdapter', '14.9.0' +# pod 'TaurusxAdsSDK','1.12.0' end diff --git a/Podfile.lock b/Podfile.lock index f382bfd..d7c7c1b 100755 --- a/Podfile.lock +++ b/Podfile.lock @@ -243,6 +243,6 @@ SPEC CHECKSUMS: YYText: 5c461d709e24d55a182d1441c41dc639a18a4849 ZLPhotoBrowser: d5928f08485c90a0b349a3a1e804e82c83ccf193 -PODFILE CHECKSUM: cd32c414c77ca06ddc270e513eb703e621fcdcff +PODFILE CHECKSUM: 7f9d52a2d48e07bbe3da45c9c5f8da06c21e4c9a COCOAPODS: 1.16.2