123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- //
- // TSPurchaseVC.swift
- // TSLiveWallpaper
- //
- // Created by 100Years on 2025/1/14.
- //
- import Combine
- import SwiftUI
- import SwiftUIX
- class PurchaseViewModel : ObservableObject{
-
- @Published var selectedType: PremiumPeriod = .year
-
- /// 订阅publisher
- let buyPublisher = PassthroughSubject<Bool,Never>()
- /// 隐私
- let privacyPublisher = PassthroughSubject<Bool, Never>()
- /// term
- let termPublisher = PassthroughSubject<Bool, Never>()
- /// restore
- let restorePublisher = PassthroughSubject<Bool, Never>()
- }
- class TSPurchaseVC: TSBaseVC {
-
- var closePageBlock:(()->Void)?
-
- var viewModel: PurchaseViewModel = .init()
- var cancellabel: [AnyCancellable] = []
- var buyPeriod:PremiumPeriod = .year
- lazy var purchaseManager: PurchaseManager = {
- let purchaseManager = PurchaseManager.default
- return purchaseManager
- }()
-
- var isHandlePurchaseStateChanged = true //是否处理购买状态变化
-
- func createImageScroll(imageName:String,direction:ImagesAnimateScrollView.`Direction`)->ImagesAnimateScrollView{
- let imageScroll1: ImagesAnimateScrollView = ImagesAnimateScrollView()
- imageScroll1.direction = direction
- imageScroll1.animationImageName = imageName
- imageScroll1.transform = CGAffineTransform(rotationAngle: CGFloat.pi/12)
- return imageScroll1
- }
-
- lazy var imageComparisonView: TYCycleImageComparisonView = {
- let imageComparisonView = TYCycleImageComparisonView()
- imageComparisonView.frame = CGRect(x: 0, y: 0, width: k_ScreenWidth, height: 532*kDesignScale)
- imageComparisonView.itemModelArray = [
- TSImageComparisonModel(oldImage: UIImage(named: "image_comparison_old_0")!, newImage: UIImage(named: "image_comparison_new_0")!),
- TSImageComparisonModel(oldImage: UIImage(named: "image_comparison_old_1")!, newImage: UIImage(named: "image_comparison_new_1")!),
- TSImageComparisonModel(oldImage: UIImage(named: "image_comparison_old_2")!, newImage: UIImage(named: "image_comparison_new_2")!),
- TSImageComparisonModel(oldImage: UIImage(named: "image_comparison_old_3")!, newImage: UIImage(named: "image_comparison_new_3")!),
- TSImageComparisonModel(oldImage: UIImage(named: "image_comparison_old_4")!, newImage: UIImage(named: "image_comparison_new_4")!)
- ]
- return imageComparisonView
- }()
-
- lazy var bgView: UIView = {
- let bgView = UIView()
- bgView.backgroundColor = .clear
- let imageView = UIImageView.createImageView(imageName: "purchase_bj",contentMode: .scaleAspectFill)
- bgView.addSubview(imageView)
-
- imageView.snp.makeConstraints { make in
- make.edges.equalToSuperview()
- }
-
- return bgView
- }()
-
- lazy var hostVc: UIHostingController<PurchaseView> = {
- //增加月付费
- // if PurchaseManager.default.vipType == .none {
- // viewModel.selectedType = .month
- // }
-
- if PurchaseManager.default.vipType == .none {
- viewModel.selectedType = .week(.week)
- }
- let vc = UIHostingController(rootView: PurchaseView(viewModel: viewModel))
- vc.view.backgroundColor = .clear
- return vc
- }()
-
- override func createView() {
- addNormalNavBarView()
- _ = setNavigationItem("", imageName: "close_gray", direction: .left, action: #selector(closePage))
-
- view.insertSubview(bgView, at: 0)
- bgView.snp.makeConstraints { make in
- make.leading.trailing.bottom.top.equalToSuperview()
- }
-
- bgView.insertSubview(imageComparisonView, at: 0)
-
- // setViewBgImageNamed(named: "purchase_bj")
- contentView.addSubview(hostVc.view)
- hostVc.view.snp.makeConstraints { make in
- make.leading.trailing.bottom.top.equalToSuperview()
- }
- }
-
- @objc func closePage(){
- TSToastShared.hideLoading()
- closePageBlock?()
- self.dismiss(animated: true)
- kPurchaseCountDownTime.isNeedCheck = true
- NotificationCenter.default.post(name: .kCloseTSPurchaseVC, object: nil)
- }
-
- override func dealThings() {
-
- //周会员和月会员不自动处理变化,必须点击购买后才处理
- let vipType = purchaseManager.vipType
- if vipType.isWeekType || vipType == .month {
- isHandlePurchaseStateChanged = false
- }
-
- addNotifaction()
- onPurchaseStateChanged()
- NotificationCenter.default.addObserver(forName: .kPurchasePrepared, object: nil, queue: OperationQueue.main) { [weak self] _ in
- guard let self = self else { return }
- viewModel.selectedType = viewModel.selectedType
- }
- }
-
-
- func addNotifaction() {
- viewModel.buyPublisher.receive(on: DispatchQueue.main).sink { [weak self] _ in
- guard let self = self else {
- return
- }
- isHandlePurchaseStateChanged = true
- PurchaseManager.default.pay(for: self.viewModel.selectedType)
- }.store(in: &cancellabel)
- viewModel.privacyPublisher.receive(on: DispatchQueue.main).sink { [weak self] _ in
- guard let self = self else {
- return
- }
-
- let vc = TSBusinessWebVC(urlType: .privacy)
- vc.hidesBottomBarWhenPushed = true
- kPresentModalVC(target: self, modelVC: vc)
-
- }.store(in: &cancellabel)
- viewModel.termPublisher.receive(on: DispatchQueue.main).sink { [weak self] _ in
- guard let self = self else {
- return
- }
-
- let vc = TSBusinessWebVC(urlType: .terms)
- vc.hidesBottomBarWhenPushed = true
- kPresentModalVC(target: self, modelVC: vc)
- }.store(in: &cancellabel)
- viewModel.restorePublisher.receive(on: DispatchQueue.main).sink { [weak self] _ in
- guard let self = self else { return }
- restorePremium()
- }.store(in: &cancellabel)
- }
-
- func restorePremium(){
- isHandlePurchaseStateChanged = true
- PurchaseManager.default.restorePremium()
- }
-
- func onPurchaseStateChanged(){
- purchaseManager.onPurchaseStateChanged = { [weak self] manager,state,object in
- guard let self = self else { return }
-
- if isHandlePurchaseStateChanged == false {
- debugPrint("purchaseManager.onPurchaseStateChanged 不处理")
- return
- }
-
- DispatchQueue.main.async {
- switch state {
- case .none:
- break
- case .loading:
- TSToastShared.showLoading(text: "Getting price".localized,containerView: self.view)
- case .loadSuccess:
- TSToastShared.hideLoading()
- case .loadFail:
- TSToastShared.hideLoading()
- let message = "Failed to get the price, will automatically retry in 5 seconds".localized
- TSToastShared.showToast(text: message)
- DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
- PurchaseManager.default.requestProducts()
- }
- case .paying:
- TSToastShared.showLoading(text: "Purchasing now".localized,containerView: self.view)
- case .paySuccess:
- TSToastShared.hideLoading()
-
- var loadingText = "Finish".localized
- if manager.isVip {
- loadingText = manager.vipType == .year ? "Congratulations on being VIP of the Year!".localized : "Congratulation you have become VIP".localized
- }
-
- TSToastShared.showToast(text:loadingText)
- if manager.isVip {
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
- self.closePage()
- }
- }
- case .payFail:
- TSToastShared.hideLoading()
- if let str = object as? String {
- TSToastShared.showToast(text: str)
- }
-
- case .restoreing:
- TSToastShared.showLoading(text: "Restoring now".localized,containerView: self.view)
- case .restoreSuccess:
- TSToastShared.hideLoading()
- // let loadingText = manager.isVip ? "Congratulation you have become VIP".localized : "Couldn't Restore Subscription".localized
- let loadingText = manager.vipType == .year ? "Congratulations on being VIP of the Year!".localized : "Congratulation you have become VIP".localized
- debugPrint(loadingText)
- TSToastShared.showToast(text:loadingText)
- if manager.isVip {
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
- self.closePage()
- }
- }
- case .restoreFail:
- TSToastShared.hideLoading()
- let loadingText = (object as? String) ?? "Failed to restore subscribe, please try again".localized
- debugPrint(loadingText)
- TSToastShared.showToast(text: loadingText)
- case .verifying:
- #if DEBUG
- TSToastShared.showLoading(text: "Verifying receipt...".localized,containerView: self.view)
- #endif
- case .verifySuccess:
- break
- case .verifyFail:
- #if DEBUG
- TSToastShared.hideLoading()
- let message = (object as? String) ?? "Failed to validate receipt".localized
- TSToastShared.showToast(text:message)
- #endif
- }
- }
- debugPrint("PurchaseManager onPurchaseStateChanged=\(String(describing: state))")
- }
- }
-
- override func viewWillAppear(_ animated: Bool) {
- super.viewWillAppear(animated)
- // 禁用右滑返回手势
- navigationController?.interactivePopGestureRecognizer?.isEnabled = false
- }
- override func viewWillDisappear(_ animated: Bool) {
- super.viewWillDisappear(animated)
- // 恢复右滑返回手势
- navigationController?.interactivePopGestureRecognizer?.isEnabled = true
- }
-
- deinit {
- cancellabel.removeAll()
- }
- }
- func kJudgeVipFreeType(vipFreeNumType:VipFreeNumType,
- vc:UIViewController? = nil,
- closePageBlock:(()->Void)? = nil) -> Bool {
- //判断 vip
- return kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: vipFreeNumType) == false, vc: vc ,closePageBlock: closePageBlock)
- }
- func kJudgeVip(externalBool:Bool,
- vc:UIViewController? = nil,
- closePageBlock:(()->Void)? = nil) -> Bool {
- //判断 vip
- if externalBool,
- PurchaseManager.default.isVip == false
- {
- if let vc = vc {
- TSPurchaseVC.show(target: vc, closePageBlock: nil)
- }else if let rootVC = WindowHelper.getRootViewController() {
- TSPurchaseVC.show(target: rootVC, closePageBlock: nil)
- }
- return true
- }
- return false
- }
- extension TSPurchaseVC{
-
- static func show(target:UIViewController,closePageBlock:(()->Void)? = nil){
- kDelayMainShort {
- let vc = TSPurchaseVC()
- vc.closePageBlock = closePageBlock
- let navi = TSBaseNavigationC(rootViewController: vc)
- navi.modalPresentationStyle = .overFullScreen
- target.present(navi, animated: true)
- }
- }
- }
|