// // KMProductModel.swift // PDF Reader Pro // // Created by wanjun on 2024/11/6. // import Foundation import Combine @objc enum KMCompareTableType : Int { case trial = 0 // 试用比较表 case dmg_Base // DMG 基础版 case dmg_MacWindows // DMG Mac&Windows双平台高级版永久 case lite_Base // Lite 基础版 case lite_MacWindows // Lite Mac&Windows双平台高级版永久 case pro_Base // Pro 基础版 case pro_Advanced // Pro Mac单平台高级版永久 } @objc enum KMCompareProductType : Int { case free = 0 // 免费 case freeTrial // 试用 case allPlatformStandard // 全平台标准版年订阅 case dualPlatformAdvanced // Mac&Windows双平台高级版永久 case allPlatformAdvanced_6 // 全平台高级版6个月订阅 case allPlatformAdvanced_12 // 全平台高级版12个月订阅 case macPlatformAdvanced // MAC单平台高级版永久 } @objc enum KMPurchasedProductType : Int { case fourDevicesAllAccessPackNew6months_lite = 0 // 4_devices_all_access_pack_new_6months(订阅) case fourDevicesAllAccessPackNew12months_lite // 4_devices_all_access_pack_12months(订阅) // case allAccessPackNew6months_lite // all_access_pack_new_6months(订阅) // case allAccessPack12months_lite // all_access_pack_12months(订阅) // case allAccessPack6months_lite // all_access_pack_6months(订阅) case aiAllAccessPack1month_lite // ai_all_access_pack_1month(订阅) case aiAllAccessPack12month_lite // ai_all_access_pack_12month(订阅) case allAccessPackPermanent_lite // all_access_pack_permanent(永久) case advancedAddDevicesAllAccessPack12months_lite // advanced_add_devices_all_access_pack_12months(订阅) case advancedAdd2DevicesAllAccessPack12months_lite // advanced_add_2_devices_all_access_pack_12months(订阅) case aiAllAccessPack1month_pro // ai_all_access_pack_1month(订阅) case aiAllAccessPack12month_pro // ai_all_access_pack_1month(订阅) case pdfToOfficePackPermanent_pro // pdf_to_office_pack_permanent(永久) case fourDevicesAllAccessPack12months_pro // 4_devices_all_access_pack_12months(全平台高级年订阅) case standardAddDevicesAllAccessPack12months_pro // standard_add_devices_all_access_pack_12months(订阅) case advancedAddDevicesAllAccessPack12months_pro // advanced_add_devices_all_access_pack_12months(订阅) case advancedAdd2DevicesAllAccessPack12months_pro // advanced_add_2_devices_all_access_pack_12months(订阅) } typealias AppstorePurchaseComplete = (_ success: Bool,_ msg: String) -> Void @objcMembers class KMProductModel: ObservableObject { /** 比较表类型 */ @Published var state: KMCompareTableType = .trial /** 高级版半年 或 年订阅,true为年订阅,false为半年订阅,默认true为年订阅 */ @Published var isPurchaseSwitch: Bool = true // MARK: DMG Public Property /** DMG 版本所有已经上架产品记录(暂时无教育优惠) */ var dmgProductDatas: KMMemberProductResult? /** DMG 版本 已经登录用户 最后一次价格价格获取 */ var dmgLastGetProductPriceInfos: KMMemberProductResult? /** DMG 版本 已经登录用户 最后一次价格价格获取 */ var dmgLastGetBatchProductPriceInfos: KMMemberProductResult? // MARK: DMG Public Method func checkConnectionAvailable() -> Void { if KMMemberCenterManager.manager.isConnectionAvailable() == false { let alert = NSAlert() alert.alertStyle = .critical alert.messageText = NSLocalizedString("Error Information", comment: "") alert.informativeText = NSLocalizedString("Please make sure your internet connection is available.", comment: "") alert.addButton(withTitle: NSLocalizedString("OK", comment: "")) alert.runModal() return } } /** @abstract 获取服务器架上所有商品 (得到的价格是原始价格) @param */ func getDMGProductDatas() -> Void { checkConnectionAvailable() KMMemberCenterManager.manager.getListingProducts(isEducation: 0) { [weak self] success, result in guard let productsArrays : KMMemberProductResult = result else { return } self?.dmgProductDatas = productsArrays } if KMMemberInfo.shared.isLogin { getDMGProductPriceInfosForMember(productId: "SP2024102100002", isEducation: 0) { [weak self] success, result in } } } /** @abstract 获取登录用户价格(建立订单时需要用到) @param */ func getDMGProductPriceInfosForMember(productId: String, isEducation: Int, _ complete: @escaping KMMemberProductComplete) { checkConnectionAvailable() //暂时无教育优惠,先固定传 0 KMMemberCenterManager.manager.getProductPriceForBuy(productId: productId, isEducation: 0, userId:KMMemberInfo.shared.userID) { [weak self] success, result in if success { guard let productsArrays : KMMemberProductResult = result else { complete(false, result) return } self?.dmgLastGetProductPriceInfos = productsArrays complete(true, productsArrays) } else { complete(false, result) } } } /** @abstract 获取批量阶段购买价格(建立订单时需要用到) @param */ func getDMGBatchProductPriceInfosForMember(productId: String, num: Int, _ complete: @escaping KMMemberProductComplete) { checkConnectionAvailable() KMMemberCenterManager.manager.getBatchProductPrice(productId: productId, num: num) { [weak self] success, result in if success { guard let productsArrays : KMMemberProductResult = result else { complete(false, result) return } self?.dmgLastGetBatchProductPriceInfos = productsArrays complete(true, productsArrays) } else { complete(false, result) } } } // MARK: Public Method /** @abstract 根据当前权益获取比较表类型 @param */ func getCurrentComparisonTableType() -> Void { if KMMemberInfo.shared.canTrail { state = .trial } else { #if VERSION_FREE #if VERSION_DMG // DMG if KMMemberInfo.shared.vip_levels == "1" { state = .dmg_Base } else if KMMemberInfo.shared.vip_levels == "2" { state = .dmg_MacWindows } #else // AppStore 免费版本 if KMMemberInfo.shared.vip_levels == "1" { state = .lite_Base } else if KMMemberInfo.shared.vip_levels == "2" { state = .lite_MacWindows } #endif #else // AppStore 付费版 if KMMemberInfo.shared.vip_levels == "1" { state = .pro_Base } else if KMMemberInfo.shared.vip_levels == "2" { state = .pro_Advanced } #endif } } /** 对应商品价格 */ func getProductPrice(_ type: KMPurchasedProductType) -> String { if type == .fourDevicesAllAccessPackNew6months_lite { if let product = IAPProductsManager.default().fourDevicesAllAccessPackNew6Months_lite, product.isOffers { return product.offersPrice() } else { return IAPProductsManager.default().fourDevicesAllAccessPackNew6Months_lite.price() } } else if type == .fourDevicesAllAccessPackNew12months_lite { if let product = IAPProductsManager.default().fourDevicesAllAccessPackNew12months_lite, product.isOffers { return product.offersPrice() } else { return IAPProductsManager.default().fourDevicesAllAccessPackNew12months_lite.price() } } else if type == .aiAllAccessPack1month_lite { if let product = IAPProductsManager.default().aiAllAccessPack1month_lite, product.isOffers { return product.offersPrice() } else { return IAPProductsManager.default().aiAllAccessPack1month_lite.price() } } else if type == .aiAllAccessPack12month_lite { if let product = IAPProductsManager.default().aiAllAccessPack12month_lite, product.isOffers { return product.offersPrice() } else { return IAPProductsManager.default().aiAllAccessPack12month_lite.price() } } else if type == .allAccessPackPermanent_lite { if let product = IAPProductsManager.default().allAccessPackPermanent_lite, product.isOffers { return product.offersPrice() } else { return IAPProductsManager.default().allAccessPackPermanent_lite.price() } } else if type == .advancedAddDevicesAllAccessPack12months_lite { if let product = IAPProductsManager.default().advancedAddDevicesAllAccessPack12months_lite, product.isOffers { return product.offersPrice() } else { return IAPProductsManager.default().advancedAddDevicesAllAccessPack12months_lite.price() } } else if type == .advancedAdd2DevicesAllAccessPack12months_lite { if let product = IAPProductsManager.default().advancedAdd2DevicesAllAccessPack12months_lite, product.isOffers { return product.offersPrice() } else { return IAPProductsManager.default().advancedAdd2DevicesAllAccessPack12months_lite.price() } } else if type == .aiAllAccessPack1month_pro { if let product = IAPProductsManager.default().aiAllAccessPack1month_pro, product.isOffers { return product.offersPrice() } else { return IAPProductsManager.default().aiAllAccessPack1month_pro.price() } } else if type == .aiAllAccessPack12month_pro { if let product = IAPProductsManager.default().aiAllAccessPack12month_pro, product.isOffers { return product.offersPrice() } else { return IAPProductsManager.default().aiAllAccessPack12month_pro.price() } } else if type == .pdfToOfficePackPermanent_pro { if let product = IAPProductsManager.default().pdfToOfficePackPermanent_pro, product.isOffers { return product.offersPrice() } else { return IAPProductsManager.default().pdfToOfficePackPermanent_pro.price() } } else if type == .fourDevicesAllAccessPack12months_pro { if let product = IAPProductsManager.default().fourDevicesAllAccessPack12months_pro, product.isOffers { return product.offersPrice() } else { return IAPProductsManager.default().fourDevicesAllAccessPack12months_pro.price() } } else if type == .standardAddDevicesAllAccessPack12months_pro { if let product = IAPProductsManager.default().standardAddDevicesAllAccessPack12months_pro, product.isOffers { return product.offersPrice() } else { return IAPProductsManager.default().standardAddDevicesAllAccessPack12months_pro.price() } } else if type == .advancedAddDevicesAllAccessPack12months_pro { if let product = IAPProductsManager.default().advancedAddDevicesAllAccessPack12months_pro, product.isOffers { return product.offersPrice() } else { return IAPProductsManager.default().advancedAddDevicesAllAccessPack12months_pro.price() } } else if type == .advancedAdd2DevicesAllAccessPack12months_pro { if let product = IAPProductsManager.default().advancedAdd2DevicesAllAccessPack12months_pro, product.isOffers { return product.offersPrice() } else { return IAPProductsManager.default().advancedAdd2DevicesAllAccessPack12months_pro.price() } } return "" } func appstorePurchaseAction(_ tag: Int, _ complete: @escaping AppstorePurchaseComplete) -> Void { if state == .dmg_Base { } else if state == .dmg_MacWindows { } else if state == .lite_Base { if tag == 0 { if isPurchaseSwitch { membershipPurchase(.fourDevicesAllAccessPackNew12months_lite) } else { membershipPurchase(.fourDevicesAllAccessPackNew6months_lite) } } else if tag == 3 { membershipPurchase(.allAccessPackPermanent_lite) } else { membershipPurchase(.fourDevicesAllAccessPackNew12months_lite) } } else if state == .lite_MacWindows { if tag == 2 { let platforms = KMMemberInfo.shared.vip_platforms let platformsArray = platforms .components(separatedBy: ",") .map { $0.trimmingCharacters(in: .whitespaces) } if platformsArray.count == 1 { membershipPurchase(.advancedAddDevicesAllAccessPack12months_lite) } else if platformsArray.count == 2 { membershipPurchase(.advancedAdd2DevicesAllAccessPack12months_lite) } else { membershipPurchase(.advancedAdd2DevicesAllAccessPack12months_lite) } } } else if state == .pro_Base { if KMMemberInfo.shared.userScenarioType == .pro_type3 { if tag == 2 { membershipPurchase(.standardAddDevicesAllAccessPack12months_pro) } else if tag == 3 { membershipPurchase(.pdfToOfficePackPermanent_pro) } } } else if state == .pro_Advanced { if KMMemberInfo.shared.userScenarioType == .pro_type1 { membershipPurchase(.advancedAddDevicesAllAccessPack12months_pro) } else if KMMemberInfo.shared.userScenarioType == .pro_type4 { membershipPurchase(.advancedAddDevicesAllAccessPack12months_pro) } } else { if tag == 2 { membershipPurchase(.fourDevicesAllAccessPackNew12months_lite) } } } var isCancelAutoRenew: Bool { return IAPProductsManager.default().isCancelAutoRenew() } var isShowSale: Bool { if #available(macOS 10.14.4, *), isCancelAutoRenew { let manager = IAPProductsManager.default() let isSubscribed_newlyMonth = manager?.allAccessPackNew6months_lite.isSubscribed ?? false let isSubscribed_year = manager?.allAccessPack12months_lite.isSubscribed ?? false if isSubscribed_newlyMonth || isSubscribed_year { return false } if let info = KMAdvertisementManager.manager.info.StoreUserRecovery?.content?.first, !(info.show! as NSString).boolValue { return false } return true } return false } // MARK: Private Method /** 会员购买 */ private func membershipPurchase(_ type: KMPurchasedProductType) -> Void { if type == .fourDevicesAllAccessPackNew6months_lite || type == .fourDevicesAllAccessPackNew12months_lite { if isPurchaseSwitch { IAPProductsManager.default().makeSubProduct(IAPProductsManager.default().fourDevicesAllAccessPackNew12months_lite, discount: isCancelAutoRenew) } else { IAPProductsManager.default().makeSubProduct(IAPProductsManager.default().fourDevicesAllAccessPackNew6Months_lite, discount: isCancelAutoRenew) } } else if type == .aiAllAccessPack1month_lite { IAPProductsManager.default().makeSubProduct(IAPProductsManager.default().aiAllAccessPack1month_lite, discount: isCancelAutoRenew) } else if type == .aiAllAccessPack12month_lite { IAPProductsManager.default().makeSubProduct(IAPProductsManager.default().aiAllAccessPack12month_lite, discount: isCancelAutoRenew) } else if type == .allAccessPackPermanent_lite { IAPProductsManager.default().makeSubProduct(IAPProductsManager.default().allAccessPackPermanent_lite, discount: isCancelAutoRenew) } else if type == .advancedAddDevicesAllAccessPack12months_lite { IAPProductsManager.default().makeSubProduct(IAPProductsManager.default().advancedAddDevicesAllAccessPack12months_lite, discount: isCancelAutoRenew) } else if type == .advancedAdd2DevicesAllAccessPack12months_lite { IAPProductsManager.default().makeSubProduct(IAPProductsManager.default().advancedAdd2DevicesAllAccessPack12months_lite, discount: isCancelAutoRenew) } else if type == .aiAllAccessPack1month_pro { IAPProductsManager.default().makeSubProduct(IAPProductsManager.default().aiAllAccessPack1month_pro, discount: isCancelAutoRenew) } else if type == .aiAllAccessPack12month_pro { IAPProductsManager.default().makeSubProduct(IAPProductsManager.default().aiAllAccessPack12month_pro, discount: isCancelAutoRenew) } else if type == .pdfToOfficePackPermanent_pro { IAPProductsManager.default().makeSubProduct(IAPProductsManager.default().pdfToOfficePackPermanent_pro, discount: isCancelAutoRenew) } else if type == .fourDevicesAllAccessPack12months_pro { IAPProductsManager.default().makeSubProduct(IAPProductsManager.default().fourDevicesAllAccessPack12months_pro, discount: isCancelAutoRenew) } else if type == .standardAddDevicesAllAccessPack12months_pro { IAPProductsManager.default().makeSubProduct(IAPProductsManager.default().standardAddDevicesAllAccessPack12months_pro, discount: isCancelAutoRenew) } else if type == .advancedAddDevicesAllAccessPack12months_pro { IAPProductsManager.default().makeSubProduct(IAPProductsManager.default().advancedAddDevicesAllAccessPack12months_pro, discount: isCancelAutoRenew) } else if type == .advancedAdd2DevicesAllAccessPack12months_pro { IAPProductsManager.default().makeSubProduct(IAPProductsManager.default().advancedAdd2DevicesAllAccessPack12months_pro, discount: isCancelAutoRenew) } } // MARK: Action Method /** 恢复购买 */ func productRestore() -> Void { IAPProductsManager.default().restoreSubscriptions() } func privacyPolicyAction() -> Void { NSWorkspace.shared.open(URL(string: "https://www.pdfreaderpro.com/privacy-policy")!) } func termOfSerAction() -> Void { NSWorkspace.shared.open(URL(string: "https://www.pdfreaderpro.com/terms_of_service")!) } // MARK: Get & Set /** 当前比较表产品列表内容 */ var products: [KMCompareProductType] { if state == .trial { return [.free, .freeTrial] } else if state == .dmg_Base { return [.free, .allPlatformStandard, .allPlatformAdvanced_12, .dualPlatformAdvanced] } else if state == .dmg_MacWindows { return [.allPlatformAdvanced_12] } else if state == .lite_Base { return [.free, .allPlatformAdvanced_6, .allPlatformAdvanced_12, .dualPlatformAdvanced] } else if state == .lite_MacWindows { return [.allPlatformAdvanced_12] } else if state == .pro_Base { return [.allPlatformAdvanced_12, .macPlatformAdvanced] } else if state == .pro_Advanced { return [.allPlatformAdvanced_12] } return [] } /** 比较表数据源 */ var dataSource: [Any] { if isPurchaseSwitch { // 试用 全平台标准版年订阅 全平台高级版6/12个月订阅 Mac&Windows双平台高级版永久 MAC单平台高级版永久 //MAC单平台标准版永久 return [ "Benefit", ["Supported platforms", "mac, windows, ios, android", "mac, windows, ios, android", "mac, windows, ios, android", "mac, windows", "mac"], ["Maximum number of accessible devices", "2 devices", "4 devices", "4 devices", "2 devices", "1 devices"], "PDF to Office", ["Convert PDFs to Word, HTML, TXT, JPEG or PNG files", "Only first 10 pages", "Standard", "Advanced", "Advanced", "Advanced"], ["Turn PDF to PPT, Excel, RTF, CSV, and more", "Only first 10 pages", "Only first 10 pages", "✓", "✓", "✓"], ["Convert PDF to TIFF, BMP, GIF or TGA files", "Only first 10 pages", "Only first 10 pages", "✓", "✓", "✓"], "Edit PDF", ["Add and edit text in PDF", "X", "✓", "✓", "✓", "✓"], ["Edit, crop, replace image in PDF", "X", "✓", "✓", "✓", "✓"], "OCR", ["Extract texts from image-based or scanned PDF", "X", "✓", "✓", "✓", "✓"], "Organize Pages", ["Extract, rotate, rearrange, replace, add, delete pages", "X", "✓", "✓", "✓", "✓"], ["Split PDFs into multiple files", "X", "✓", "✓", "✓", "✓"], "Advanced Editing Tools", ["Merge multiple documents into a new PDF", "Up to 2 files or 20 MB", "✓", "✓", "✓", "∞", "∞"], ["Add & edit watermark", "X", "✓", "✓", "✓", "✓"], ["Add header, footer, page numbers", "X", "✓", "✓", "✓", "✓"], ["Add Bates Number", "X", "✓", "✓", "✓", "✓"], ["Insert PDF page background by color or image", "X", "✓", "✓", "✓", "✓"], ["Create fattened copies", "X", "✓", "✓", "✓", "✓"], ["Extract Images", "X", "✓", "✓", "✓", "✓"], ["Extract tables", "Only first 10 pages", "Only first 10 pages", "✓", "✓", "✓"], ["Measuring Tools", "X", "✓", "✓", "✓", "✓"], "Fill & Sign", ["Create digital signature", "X", "✓", "✓", "✓", "✓"], ["Create & Edit & Fill Adobe Fillable PDF Forms", "X", "✓", "✓", "✓", "✓"], "Security", ["Batch encrypting PDF documents", "X", "✓", "✓", "✓", "✓"], ["PDF Password Remover", "X", "✓", "✓", "✓", "✓"], ["Redact sensitive information", "X", "✓", "✓", "✓", "✓"], "Create PDF", ["Convert JPEG, JPG, PNG, TIFF, BMP or PSD files to PDFs", "1 file", "✓", "✓", "✓", "✓"], ["Create PDFs from a scanner and iOS devices", "X", "✓", "✓", "✓", "✓"], "Annotations", ["Customize PDF stamps", "X", "✓", "✓", "✓", "✓"], ["Hyperlink", "Page Number", "Page Number, URL, Email", "Page Number, URL, Email", "Page Number, URL, Email", "Page Number, URL, Email"], ["Signature", "Standard", "Advanced", "Advanced", "Advanced", "Advanced"], ["Table", "X", "✓", "✓", "✓", "✓"], "View PDF", ["Multi-tab viewer", "X", "✓", "✓", "✓", "✓"], ["Various printing types: poster, booklet, multi-page printing", "X", "✓", "✓", "✓", "✓"], ["Customize theme colors: Light Mode, Dark Mode, Sepia Mode and more", "X", "✓", "✓", "✓", "✓"], ["Split View to compare files", "X", "✓", "✓", "✓", "✓"], "Subscription Based Solution", ["Access all premium features in app", "X", "12 months", "12 months", "∞", "∞"], ["Priority customer support", "X", "✓", "✓", "✓", "✓"], ["Ad-free", "X", "✓", "✓", "✓", "✓"] ] } else { return [ "Benefit", ["Supported platforms", "mac, windows, ios, android", "mac, windows, ios, android", "mac, windows, ios, android", "mac, windows", "mac"], ["Maximum number of accessible devices", "2 devices", "4 devices", "4 devices", "2 devices", "1 devices"], "PDF to Office", ["Convert PDFs to Word, HTML, TXT, JPEG or PNG files", "Only first 10 pages", "Standard", "Advanced", "Advanced", "Advanced"], ["Turn PDF to PPT, Excel, RTF, CSV, and more", "Only first 10 pages", "Only first 10 pages", "✓", "✓", "✓"], ["Convert PDF to TIFF, BMP, GIF or TGA files", "Only first 10 pages", "Only first 10 pages", "✓", "✓", "✓"], "Edit PDF", ["Add and edit text in PDF", "X", "✓", "✓", "✓", "✓"], ["Edit, crop, replace image in PDF", "X", "✓", "✓", "✓", "✓"], "OCR", ["Extract texts from image-based or scanned PDF", "X", "✓", "✓", "✓", "✓"], "Organize Pages", ["Extract, rotate, rearrange, replace, add, delete pages", "X", "✓", "✓", "✓", "✓"], ["Split PDFs into multiple files", "X", "✓", "✓", "✓", "✓"], "Advanced Editing Tools", ["Merge multiple documents into a new PDF", "Up to 2 files or 20 MB", "✓", "✓", "✓", "∞", "∞"], ["Add & edit watermark", "X", "✓", "✓", "✓", "✓"], ["Add header, footer, page numbers", "X", "✓", "✓", "✓", "✓"], ["Add Bates Number", "X", "✓", "✓", "✓", "✓"], ["Insert PDF page background by color or image", "X", "✓", "✓", "✓", "✓"], ["Create fattened copies", "X", "✓", "✓", "✓", "✓"], ["Extract Images", "X", "✓", "✓", "✓", "✓"], ["Extract tables", "Only first 10 pages", "Only first 10 pages", "✓", "✓", "✓"], ["Measuring Tools", "X", "✓", "✓", "✓", "✓"], "Fill & Sign", ["Create digital signature", "X", "✓", "✓", "✓", "✓"], ["Create & Edit & Fill Adobe Fillable PDF Forms", "X", "✓", "✓", "✓", "✓"], "Security", ["Batch encrypting PDF documents", "X", "✓", "✓", "✓", "✓"], ["PDF Password Remover", "X", "✓", "✓", "✓", "✓"], ["Redact sensitive information", "X", "✓", "✓", "✓", "✓"], "Create PDF", ["Convert JPEG, JPG, PNG, TIFF, BMP or PSD files to PDFs", "1 file", "✓", "✓", "✓", "✓"], ["Create PDFs from a scanner and iOS devices", "X", "✓", "✓", "✓", "✓"], "Annotations", ["Customize PDF stamps", "X", "✓", "✓", "✓", "✓"], ["Hyperlink", "Page Number", "Page Number, URL, Email", "Page Number, URL, Email", "Page Number, URL, Email", "Page Number, URL, Email"], ["Signature", "Standard", "Advanced", "Advanced", "Advanced", "Advanced"], ["Table", "X", "✓", "✓", "✓", "✓"], "View PDF", ["Multi-tab viewer", "X", "✓", "✓", "✓", "✓"], ["Various printing types: poster, booklet, multi-page printing", "X", "✓", "✓", "✓", "✓"], ["Customize theme colors: Light Mode, Dark Mode, Sepia Mode and more", "X", "✓", "✓", "✓", "✓"], ["Split View to compare files", "X", "✓", "✓", "✓", "✓"], "Subscription Based Solution", ["Access all premium features in app", "X", "6 months", "6 months", "∞", "∞"], ["Priority customer support", "X", "✓", "✓", "✓", "✓"], ["Ad-free", "X", "✓", "✓", "✓", "✓"] ] } } }