Sfoglia il codice sorgente

给订阅购买类,抽离下

100Years 1 mese fa
parent
commit
8035a81898

+ 13 - 1
AIRingtone.xcodeproj/project.pbxproj

@@ -104,6 +104,7 @@
 		A899D3602D82C8D800AB9C1C /* TSPurchaseManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A899D35E2D82C8D800AB9C1C /* TSPurchaseManager.swift */; };
 		A899D3602D82C8D800AB9C1C /* TSPurchaseManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A899D35E2D82C8D800AB9C1C /* TSPurchaseManager.swift */; };
 		A899D3622D82D89C00AB9C1C /* TSButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = A899D3612D82D89000AB9C1C /* TSButton.swift */; };
 		A899D3622D82D89C00AB9C1C /* TSButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = A899D3612D82D89000AB9C1C /* TSButton.swift */; };
 		A899D36F2D83C3DC00AB9C1C /* TSTutorialPopupVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A899D36E2D83C3D500AB9C1C /* TSTutorialPopupVC.swift */; };
 		A899D36F2D83C3DC00AB9C1C /* TSTutorialPopupVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A899D36E2D83C3D500AB9C1C /* TSTutorialPopupVC.swift */; };
+		A899D3742D87B15F00AB9C1C /* TSPurchaseTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = A899D3732D87B15D00AB9C1C /* TSPurchaseTool.swift */; };
 		A8C6436C2D79A8C8001068D0 /* TSAIRintoneHistoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8C6436B2D79A8C7001068D0 /* TSAIRintoneHistoryCell.swift */; };
 		A8C6436C2D79A8C8001068D0 /* TSAIRintoneHistoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8C6436B2D79A8C7001068D0 /* TSAIRintoneHistoryCell.swift */; };
 		A8CC55822D797720002E0CAA /* TSGeneralPicBrowseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8CC55812D79771F002E0CAA /* TSGeneralPicBrowseVC.swift */; };
 		A8CC55822D797720002E0CAA /* TSGeneralPicBrowseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8CC55812D79771F002E0CAA /* TSGeneralPicBrowseVC.swift */; };
 		A8CC55862D798E2D002E0CAA /* TSTextGeneralRintoneVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8CC55852D798E2D002E0CAA /* TSTextGeneralRintoneVC.swift */; };
 		A8CC55862D798E2D002E0CAA /* TSTextGeneralRintoneVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8CC55852D798E2D002E0CAA /* TSTextGeneralRintoneVC.swift */; };
@@ -219,6 +220,7 @@
 		A899D35E2D82C8D800AB9C1C /* TSPurchaseManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPurchaseManager.swift; sourceTree = "<group>"; };
 		A899D35E2D82C8D800AB9C1C /* TSPurchaseManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPurchaseManager.swift; sourceTree = "<group>"; };
 		A899D3612D82D89000AB9C1C /* TSButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSButton.swift; sourceTree = "<group>"; };
 		A899D3612D82D89000AB9C1C /* TSButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSButton.swift; sourceTree = "<group>"; };
 		A899D36E2D83C3D500AB9C1C /* TSTutorialPopupVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSTutorialPopupVC.swift; sourceTree = "<group>"; };
 		A899D36E2D83C3D500AB9C1C /* TSTutorialPopupVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSTutorialPopupVC.swift; sourceTree = "<group>"; };
+		A899D3732D87B15D00AB9C1C /* TSPurchaseTool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPurchaseTool.swift; sourceTree = "<group>"; };
 		A8C6436B2D79A8C7001068D0 /* TSAIRintoneHistoryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIRintoneHistoryCell.swift; sourceTree = "<group>"; };
 		A8C6436B2D79A8C7001068D0 /* TSAIRintoneHistoryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIRintoneHistoryCell.swift; sourceTree = "<group>"; };
 		A8CC55812D79771F002E0CAA /* TSGeneralPicBrowseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGeneralPicBrowseVC.swift; sourceTree = "<group>"; };
 		A8CC55812D79771F002E0CAA /* TSGeneralPicBrowseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGeneralPicBrowseVC.swift; sourceTree = "<group>"; };
 		A8CC55852D798E2D002E0CAA /* TSTextGeneralRintoneVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSTextGeneralRintoneVC.swift; sourceTree = "<group>"; };
 		A8CC55852D798E2D002E0CAA /* TSTextGeneralRintoneVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSTextGeneralRintoneVC.swift; sourceTree = "<group>"; };
@@ -792,11 +794,20 @@
 		A899D35F2D82C8D800AB9C1C /* Purchase */ = {
 		A899D35F2D82C8D800AB9C1C /* Purchase */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
-				A899D35E2D82C8D800AB9C1C /* TSPurchaseManager.swift */,
+				A899D3722D87B15100AB9C1C /* TSPurchaseManager */,
 			);
 			);
 			path = Purchase;
 			path = Purchase;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		A899D3722D87B15100AB9C1C /* TSPurchaseManager */ = {
+			isa = PBXGroup;
+			children = (
+				A899D35E2D82C8D800AB9C1C /* TSPurchaseManager.swift */,
+				A899D3732D87B15D00AB9C1C /* TSPurchaseTool.swift */,
+			);
+			path = TSPurchaseManager;
+			sourceTree = "<group>";
+		};
 		A8C6436A2D79A8BD001068D0 /* View */ = {
 		A8C6436A2D79A8BD001068D0 /* View */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
@@ -982,6 +993,7 @@
 			isa = PBXSourcesBuildPhase;
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
+				A899D3742D87B15F00AB9C1C /* TSPurchaseTool.swift in Sources */,
 				A868A9072D77EED800F6D884 /* TSTGPTitleView.swift in Sources */,
 				A868A9072D77EED800F6D884 /* TSTGPTitleView.swift in Sources */,
 				A868A8C22D76A2A700F6D884 /* UIFont+TSEx.swift in Sources */,
 				A868A8C22D76A2A700F6D884 /* UIFont+TSEx.swift in Sources */,
 				A868A91A2D78559800F6D884 /* TSProgressState.swift in Sources */,
 				A868A91A2D78559800F6D884 /* TSProgressState.swift in Sources */,

+ 1 - 1
AIRingtone.xcodeproj/xcshareddata/xcschemes/AIRingtone.xcscheme

@@ -31,7 +31,7 @@
       shouldAutocreateTestPlan = "YES">
       shouldAutocreateTestPlan = "YES">
    </TestAction>
    </TestAction>
    <LaunchAction
    <LaunchAction
-      buildConfiguration = "Debug"
+      buildConfiguration = "Release"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       launchStyle = "0"
       launchStyle = "0"

+ 2 - 2
AIRingtone/Business/LaunchVC/TSLaunchVC.swift

@@ -37,14 +37,14 @@ class TSLaunchVC: UIViewController {
         TSNetworkShared.startListenNetStatus { status, manager in
         TSNetworkShared.startListenNetStatus { status, manager in
             switch status {
             switch status {
             case .reachable:
             case .reachable:
-                kPurchaseDefault.requestProducts()
+                kPurchaseToolShared.luanchuPrchase()
 //                AppDelegate.requestAdTrack()
 //                AppDelegate.requestAdTrack()
                 manager?.stopListening()
                 manager?.stopListening()
 //                self.initAdMob()
 //                self.initAdMob()
                 break
                 break
             default:
             default:
 //                AppDelegate.requestAdTrack()
 //                AppDelegate.requestAdTrack()
-                kPurchaseDefault.requestProducts()
+                kPurchaseToolShared.luanchuPrchase()
 //                self.initAdMob()
 //                self.initAdMob()
                 break
                 break
             }
             }

+ 1 - 1
AIRingtone/Business/TSAIPhotoVC/TSGeneralPicVC/TSGeneralPicVC+Event.swift

@@ -141,7 +141,7 @@ extension TSGeneralPicVC {
             guard let self = self else { return }
             guard let self = self else { return }
         }
         }
         
         
-        kPurchaseDefault.useOnceForFree(type: vipFreeNumType)
+        kPurchaseToolShared.useOnceForFree(type: vipFreeNumType)
         
         
         if let model = imageModel {
         if let model = imageModel {
             complete(model)
             complete(model)

+ 2 - 2
AIRingtone/Business/TSAIPhotoVC/TSGeneralPicVC/TSGeneralPicVC.swift

@@ -87,7 +87,7 @@ class TSGeneralPicVC: TSBottomAlertVC {
     
     
     override func clickAgainBtn() {
     override func clickAgainBtn() {
         //判断 vip
         //判断 vip
-        if kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: vipFreeNumType) == false, vc: self) {[weak self] in
+        if kJudgeVip(externalBool: kPurchaseToolShared.freeNumAvailable(type: vipFreeNumType) == false, vc: self) {[weak self] in
             guard let self = self else { return }
             guard let self = self else { return }
         }{ return }
         }{ return }
         viewModel.creatImageEmoji(text:aiText)
         viewModel.creatImageEmoji(text:aiText)
@@ -116,7 +116,7 @@ class TSGeneralPicVC: TSBottomAlertVC {
 
 
     override func dealThings() {
     override func dealThings() {
         //判断 vip
         //判断 vip
-        if kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: vipFreeNumType) == false, vc: self) {[weak self] in
+        if kJudgeVip(externalBool: kPurchaseToolShared.freeNumAvailable(type: vipFreeNumType) == false, vc: self) {[weak self] in
             guard let self = self else { return }
             guard let self = self else { return }
         }{ return }
         }{ return }
         viewModel.creatImageEmoji(text: self.aiText)
         viewModel.creatImageEmoji(text: self.aiText)

+ 1 - 1
AIRingtone/Business/TSAIPhotoVC/TSTextGeneralPicVC/TSTextGeneralPicVC.swift

@@ -168,7 +168,7 @@ extension TSTextGeneralPicVC {
     func generateImage() {
     func generateImage() {
 
 
         //判断 vip
         //判断 vip
-        if kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: vipFreeNumType) == false, vc: self) {[weak self] in
+        if kJudgeVip(externalBool: kPurchaseToolShared.freeNumAvailable(type: vipFreeNumType) == false, vc: self) {[weak self] in
             guard let self = self else { return }
             guard let self = self else { return }
         }{ return }
         }{ return }
         
         

+ 1 - 1
AIRingtone/Business/TSAIRintoneVC/TSGeneralRintoneVC/TSGeneralRintoneVC+Event.swift

@@ -86,7 +86,7 @@ extension TSGeneralRintoneVC {
         ringView.isHidden = false
         ringView.isHidden = false
         regenerateBtn.isHidden = false
         regenerateBtn.isHidden = false
         
         
-        kPurchaseDefault.useOnceForFree(type: .ringtones)
+        kPurchaseToolShared.useOnceForFree(type: .ringtones)
         
         
         if let model = infoModel {
         if let model = infoModel {
             complete(model)
             complete(model)

+ 2 - 2
AIRingtone/Business/TSAIRintoneVC/TSGeneralRintoneVC/TSGeneralRintoneVC.swift

@@ -90,7 +90,7 @@ class TSGeneralRintoneVC: TSBottomAlertVC {
     override func clickAgainBtn() {
     override func clickAgainBtn() {
         audioPlayer.stop()
         audioPlayer.stop()
         //判断 vip
         //判断 vip
-        if kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: .ringtones) == false, vc: self) {[weak self] in
+        if kJudgeVip(externalBool: kPurchaseToolShared.freeNumAvailable(type: .ringtones) == false, vc: self) {[weak self] in
             guard let self = self else { return }
             guard let self = self else { return }
         }{ return }
         }{ return }
         viewModel.creatRintone(text:aiText)
         viewModel.creatRintone(text:aiText)
@@ -118,7 +118,7 @@ class TSGeneralRintoneVC: TSBottomAlertVC {
     
     
     override func dealThings() {
     override func dealThings() {
         //判断 vip
         //判断 vip
-        if kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: .ringtones) == false, vc: self) {[weak self] in
+        if kJudgeVip(externalBool: kPurchaseToolShared.freeNumAvailable(type: .ringtones) == false, vc: self) {[weak self] in
             guard let self = self else { return }
             guard let self = self else { return }
         }{ return }
         }{ return }
         viewModel.creatRintone(text: self.aiText)
         viewModel.creatRintone(text: self.aiText)

+ 1 - 1
AIRingtone/Business/TSAIRintoneVC/TSTextGeneralRintoneVC/TSTextGeneralRintoneVC.swift

@@ -127,7 +127,7 @@ extension TSTextGeneralRintoneVC {
     func generateImage() {
     func generateImage() {
         
         
         //判断 vip
         //判断 vip
-        if kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: .ringtones) == false, vc: self) {[weak self] in
+        if kJudgeVip(externalBool: kPurchaseToolShared.freeNumAvailable(type: .ringtones) == false, vc: self) {[weak self] in
             guard let self = self else { return }
             guard let self = self else { return }
         }{ return }
         }{ return }
         
         

+ 74 - 0
AIRingtone/Business/VIewTool/TSButton.swift

@@ -24,3 +24,77 @@ class TSNormalCancelBtn: TSAppBtn {
 
 
 }
 }
 
 
+//常用提交按钮
+func kCreateNormalSubmitBtn(title:String, action: (() -> Void)? = nil) -> UIButton {
+    
+    let btn = TSNormalSubmitBtn()
+    btn.setUpButton(title:title,font: UIFont.font(size: 16,weight: .regular),titleColor:.white,corner: 24,action: action)
+    btn.contentEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 0)
+    btn.imageEdgeInsets = UIEdgeInsets(top:0, left: -8, bottom: 0, right: 16)
+    btn.frame = CGRectMake(0, 0, 200, 48)
+    btn.addGradientBg(colors: ["#E961F6".uiColor.cgColor,"#7E57F4".uiColor.cgColor])
+    return btn
+}
+
+
+class TSAppBtnView: TSBaseView {
+    enum ViewStyle {
+        case created   //创造类的按钮
+    }
+    
+    var viewH:CGFloat = 64
+    var style:ViewStyle
+    var clickBlock:()->Void
+    
+    init(style:ViewStyle,clickBlock: @escaping () -> Void) {
+        self.style = style
+        self.clickBlock = clickBlock
+        super.init(frame: .zero)
+    }
+    
+    @MainActor required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    
+    //###################################### Button ######################################
+    lazy var creatBtn:UIButton  = {
+        
+        let btn = UIButton.createButton(title:"Create Now",font: UIFont.font(size: 16,weight: .regular),titleColor:.white,corner: 24)
+        {[weak self] in
+            guard let self = self else { return }
+            clickBlock()
+        }
+        btn.frame = CGRectMake(0, 0, k_ScreenWidth - 32, 48)
+        btn.contentEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 0)
+        btn.imageEdgeInsets = UIEdgeInsets(top: 0, left: -8, bottom: 0, right: 0)
+        btn.addGradientBg(colors: ["#E961F6".uiColor.cgColor,"#7E57F4".uiColor.cgColor])
+        return btn
+    }()
+
+    
+    override func creatUI() {
+        contentView.addSubview(creatBtn)
+        creatBtn.snp.makeConstraints { make in
+            make.center.equalToSuperview()
+            make.leading.equalTo(16)
+            make.trailing.equalTo(-16)
+            make.height.equalTo(creatBtn.height)
+        }
+        setVip(vip:true)
+    }
+    
+    func setBtnEnabled(isEnabled:Bool) {
+        creatBtn.isEnabled = isEnabled
+        creatBtn.alpha = isEnabled ? 1.0 : 0.6
+    }
+    
+    func setVip(vip:Bool) {
+        if vip {
+            creatBtn.setImage(UIImage(named: "vip_icon_white"), for: .normal)
+        }else{
+            creatBtn.setImage(nil, for: .normal)
+        }
+    }
+    
+}

+ 0 - 11
AIRingtone/Business/VIewTool/TSViewTool.swift

@@ -23,17 +23,6 @@ func createBlurEffectView(style:UIBlurEffect.Style,backgroundColor:UIColor? = ni
     return blurEffectView
     return blurEffectView
 }
 }
 
 
-//常用提交按钮
-func kCreateNormalSubmitBtn(title:String, action: (() -> Void)? = nil) -> UIButton {
-    
-    let btn = TSNormalSubmitBtn()
-    btn.setUpButton(title:title,font: UIFont.font(size: 16,weight: .regular),titleColor:.white,corner: 24,action: action)
-    btn.contentEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 0)
-    btn.imageEdgeInsets = UIEdgeInsets(top:0, left: -8, bottom: 0, right: 16)
-    btn.frame = CGRectMake(0, 0, 200, 48)
-    btn.addGradientBg(colors: ["#E961F6".uiColor.cgColor,"#7E57F4".uiColor.cgColor])
-    return btn
-}
 
 
 func kAddNormalSubmitGradientBg(view:UIView){
 func kAddNormalSubmitGradientBg(view:UIView){
     kDelayMainShort {
     kDelayMainShort {

+ 2 - 83
AIRingtone/Common/Purchase/TSPurchaseManager.swift → AIRingtone/Common/Purchase/TSPurchaseManager/TSPurchaseManager.swift

@@ -58,7 +58,6 @@ public extension Notification.Name {
     static let kPurchaseDidChanged = Self.init("kPurchaseDidChanged")
     static let kPurchaseDidChanged = Self.init("kPurchaseDidChanged")
 }
 }
 
 
-private let kFreeNumKey = "kFreeNumKey"
 private let kPremiumExpiredInfoKey = "premiumExpiredInfoKey"
 private let kPremiumExpiredInfoKey = "premiumExpiredInfoKey"
 
 
 
 
@@ -69,17 +68,10 @@ public class PurchaseManager: NSObject {
     @objc public static let `default` = PurchaseManager()
     @objc public static let `default` = PurchaseManager()
 
 
     //苹果共享密钥
     //苹果共享密钥
-    private let AppleSharedKey:String = "4ed5151881304025bfee0295ee459422"
+    public var AppleSharedKey:String = ""
     
     
     //商品信息
     //商品信息
-    public lazy var purchaseProducts:[PurchaseProduct] = {
-        return [
-            PurchaseProduct(productId: "01", period:.month),
-//            PurchaseProduct(productId: "102", period:.year),
-//            PurchaseProduct(productId: "103", period:.week),
-            //PurchaseProduct(productId: "003", period: .lifetime),
-        ]
-    }()
+    public lazy var purchaseProducts:[PurchaseProduct] = []
 
 
     struct Config {
     struct Config {
         static let verifyUrl = "https://buy.itunes.apple.com/verifyReceipt"
         static let verifyUrl = "https://buy.itunes.apple.com/verifyReceipt"
@@ -93,9 +85,6 @@ public class PurchaseManager: NSObject {
     // 会员信息
     // 会员信息
     var vipInformation: [String: Any] = [:]
     var vipInformation: [String: Any] = [:]
 
 
-    // 免费使用会员的次数
-    var freeDict:[String:Int] = [:]
-        
     //原始订单交易id dict
     //原始订单交易id dict
     var originalTransactionIdentifierDict:[String:String] = [:]
     var originalTransactionIdentifierDict:[String:String] = [:]
     
     
@@ -107,8 +96,6 @@ public class PurchaseManager: NSObject {
         if let info = UserDefaults.standard.object(forKey: kPremiumExpiredInfoKey) as? [String: Any] {
         if let info = UserDefaults.standard.object(forKey: kPremiumExpiredInfoKey) as? [String: Any] {
             vipInformation = info
             vipInformation = info
         }
         }
-        
-        initializeForFree()
     }
     }
 
 
     public var expiredDate: Date? {
     public var expiredDate: Date? {
@@ -541,74 +528,6 @@ public extension PurchaseManager {
     }
     }
 }
 }
 
 
-
-/// 免费生成图片次数
-extension PurchaseManager {
-    /// 使用一次免费次数
-    func useOnceForFree(type:VipFreeNumType){
-        
-        if isVip {
-            return
-        }
-        
-        var freeNum = freeDict[type.rawValue] ?? 0
-        if freeNum > 0 {
-            freeNum-=1
-        }
-        
-        if freeNum < 0 {
-            freeNum = 0
-        }
-        
-        freeDict[type.rawValue] = freeNum
-        saveForFree()
-    }
-    
-    func freeNum(type:VipFreeNumType) -> Int{
-        let freeNum = freeDict[type.rawValue] ?? 0
-        return freeNum
-    }
-    
-    func saveForFree(){
-        UserDefaults.standard.set(freeDict, forKey: kFreeNumKey)
-        UserDefaults.standard.synchronize()
-    }
-    
-    func initializeForFree(){
-        if let dict = UserDefaults.standard.dictionary(forKey: kFreeNumKey) as? [String:Int]{
-            freeDict = dict
-        }else{
-            freeDict = [
-                VipFreeNumType.ringtones.rawValue:1,
-                VipFreeNumType.posetr.rawValue:1,
-                VipFreeNumType.photo.rawValue:1
-            ]
-            saveForFree()
-        }
-    }
-    
-    /// 免费次数是否可用
-    func freeNumAvailable(type:VipFreeNumType) -> Bool{
-        if isVip == true {
-            return true
-        }else{
-            if let freeNum = freeDict[type.rawValue],freeNum > 0 {
-                return true
-            }
-        }
-        return false
-    }
-    
-    /// 是否展示生成类的会员图标
-    func generateVipShow(type:VipFreeNumType) -> Bool{
-        if isVip == false, freeNum(type: type) > 0 {
-            return false
-        }
-        return true
-    }
-}
-
-
 /*
 /*
  
  
  首先,创建SKProductsRequest对象并使用init(productIdentifiers:)初始化,传入要查询的产品标识符。
  首先,创建SKProductsRequest对象并使用init(productIdentifiers:)初始化,传入要查询的产品标识符。

+ 101 - 0
AIRingtone/Common/Purchase/TSPurchaseManager/TSPurchaseTool.swift

@@ -0,0 +1,101 @@
+//
+//  TSPurchaseTool.swift
+//  AIRingtone
+//
+//  Created by 100Years on 2025/3/16.
+//
+
+/// 免费生成图片次数
+
+let kPurchaseToolShared = TSPurchaseTool.shared
+class TSPurchaseTool {
+    private let kFreeNumKey = "kFreeNumKey"
+    static let shared = TSPurchaseTool()
+
+    init() {
+        initializeForFree()
+    }
+    
+    // 免费使用会员的次数
+    var freeDict:[String:Int] = [:]
+    
+    var isVip:Bool{
+        return kPurchaseDefault.isVip
+    }
+    /// 使用一次免费次数
+    func useOnceForFree(type:VipFreeNumType){
+        
+        if isVip {
+            return
+        }
+        
+        var freeNum = freeDict[type.rawValue] ?? 0
+        if freeNum > 0 {
+            freeNum-=1
+        }
+        
+        if freeNum < 0 {
+            freeNum = 0
+        }
+        
+        freeDict[type.rawValue] = freeNum
+        saveForFree()
+    }
+    
+    func freeNum(type:VipFreeNumType) -> Int{
+        let freeNum = freeDict[type.rawValue] ?? 0
+        return freeNum
+    }
+    
+    func saveForFree(){
+        UserDefaults.standard.set(freeDict, forKey: kFreeNumKey)
+        UserDefaults.standard.synchronize()
+    }
+    
+    func initializeForFree(){
+        if let dict = UserDefaults.standard.dictionary(forKey: kFreeNumKey) as? [String:Int]{
+            freeDict = dict
+        }else{
+            freeDict = [
+                VipFreeNumType.ringtones.rawValue:1,
+                VipFreeNumType.posetr.rawValue:1,
+                VipFreeNumType.photo.rawValue:1
+            ]
+            saveForFree()
+        }
+    }
+    
+    /// 免费次数是否可用
+    func freeNumAvailable(type:VipFreeNumType) -> Bool{
+        if isVip == true {
+            return true
+        }else{
+            if let freeNum = freeDict[type.rawValue],freeNum > 0 {
+                return true
+            }
+        }
+        return false
+    }
+    
+    /// 是否展示生成类的会员图标
+    func generateVipShow(type:VipFreeNumType) -> Bool{
+        if isVip == false, freeNum(type: type) > 0 {
+            return false
+        }
+        return true
+    }
+}
+
+extension TSPurchaseTool{
+    
+    
+    func luanchuPrchase() {
+        kPurchaseDefault.AppleSharedKey = "4ed5151881304025bfee0295ee459422"
+        kPurchaseDefault.purchaseProducts = [
+            PurchaseProduct(productId: "01", period:.month)
+        ]
+        kPurchaseDefault.requestProducts()
+        
+    }
+    
+}