// // KMWinBackWindowController.swift // PDF Reader Pro // // Created by User-Tangchao on 2025/1/13. // import Cocoa import StoreKit import SwiftUI @objcMembers class KMIAPTransaction: NSObject { var transactionIdentifier: String? var productIdentifier: String? override init() { super.init() self.transactionIdentifier = "" self.productIdentifier = "" } } let KMWinBackIAPProductPurchasedNotificationName = "KMWinBackIAPProductPurchasedNotification" //class KMWinBackWindowController: KMBaseWindowController { // @IBOutlet weak var contentBox: NSBox! // @IBOutlet weak var backgroundIv: NSImageView! // @IBOutlet weak var iconIv: NSImageView! // @IBOutlet weak var titleLabel: NSTextField! // @IBOutlet weak var subTitleLabel: NSTextField! // @IBOutlet weak var despBox: NSBox! // @IBOutlet weak var buttonBox: NSBox! // // static let shared = KMWinBackWindowController(windowNibName: "KMWinBackWindowController") // // private lazy var despView_: KMWinBackDespView = { // let view = KMWinBackDespView() // return view // }() // // private lazy var buttonView_: KMWinBackButtonView = { // let view = KMWinBackButtonView() // return view // }() // // private let showCountKey_ = "WinBackWindowShowCount" // private let lastShowTimeKey_ = "WinBackWindowLastShowTime" // // private var origialPrice_: String = "" // // private var offerId_: String? // private var displayPriceString_: String = "" // // override func windowDidLoad() { // super.windowDidLoad() // // window?.standardWindowButton(.zoomButton)?.isHidden = true // window?.standardWindowButton(.miniaturizeButton)?.isHidden = true // window?.delegate = self // let closeButton = window?.standardWindowButton(.closeButton) // closeButton?.target = self // closeButton?.action = #selector(closeAction) // // despBox.borderWidth = 0 // despBox.cornerRadius = 4 // despBox.contentView = despView_ // buttonBox.borderWidth = 0 // buttonBox.cornerRadius = 4 // buttonBox.contentView = buttonView_ // // backgroundIv.image = NSImage(named: "KMImageNameWinBackBg") // backgroundIv.image?.size = window?.frame.size ?? NSMakeSize(520, 540) // iconIv.image = NSImage(named: "KMImageNameWinBackIcon") // // titleLabel.stringValue = NSLocalizedString("PDF Reader Pro", comment: "") // titleLabel.font = .SFProTextRegularFont(20) // // despView_.titleLabel.stringValue = NSLocalizedString("PDF Reader Pro Advanced\n - 6 Months Plan", comment: "") // despView_.tipLabel.stringValue = NSLocalizedString("Because you were previously subscribed to PDF Reader Pro, we are now delivering a special offer to you. ", comment: "") // despView_.iconIv.image = NSImage(named: "KMImageNameWinBackDespIcon") // // buttonView_.backgroundView.xRadius = 4 // buttonView_.backgroundView.yRadius = 4 // // buttonView_.button.font = .SFProTextRegularFont(16) // buttonView_.itemClick = { [weak self] idx, _ in // self?.trackEvent_free(eventName: "PUW_3", params: ["PUW_Btn" : "WinBackPuw_Purchase_Click"], platform: .firebase) // // self?.purchase() // } // // origialPrice_ = _fetchOrigialPrice() ?? "" // // interfaceThemeDidChanged(self.window?.appearance?.name ?? .aqua) // // if #available(macOS 15.0, *) { // var rootView = CPDFOfferSubscriptionStoreView() // rootView.eligibleOffersCallback = { offertIds in // KMPrint("你符合赢回的优惠卷:") // KMPrint(offertIds) // if offertIds.isEmpty == false { // if let data = offertIds.first, data.isEmpty == false { // if let data = self.offerId_, data.isEmpty == false { // return // } // // if self.needShow() { // self.trackEvent_free(eventName: "PUW_3", params: ["PUW_Exposure" : "WinBackPuw_Exposure"], platform: .firebase) // // self._selectOffer(offerId: data) // // self.showWindow(nil) // // self._saveRecord() // // self.window?.makeKeyAndOrderFront(nil) // } else { // KMPrint("Win Back:不需要显示") // // self.window?.close() // } // } // } // } // let hostingView = NSHostingView(rootView: rootView) // // hostingView.frame = NSRect(x: 0, y: 0, width: 1000, height: 1000) // contentBox.addSubview(hostingView, positioned: .below, relativeTo: backgroundIv) // // hostingView.isHidden = true // } else { // self.window?.close() // } // //// https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/{transactionId} //// https://api.storekit-sandbox.itunes.apple.com/inApps/v1/subscriptions/{transactionId} // // // /2000000828945111 //// let url = "https://api.storekit-sandbox.itunes.apple.com/inApps/v1/subscriptions" ////// let urlString = KMMemberCenterConfig().activityBaseURL() + url //// // ["transactionId" : "2000000828945111"] //// KMRequestServer.requestServer.request(urlString: url, method: .get, params: nil) { requestSerializer in ////// requestSerializer.setValue("Bearer " + token, forHTTPHeaderField: "Authorization") //// } completion: { task, responseObject, error in //// guard let dict = responseObject as? [String : Any] else { ////// callback(false, nil, error) //// return //// } //// //// let model = KMRequestResultModel(dict: dict) ////// callback(model.isSuccess(), model, error) //// } //// KMRequestServer.requestServer.request(urlString: url, method: .get, params: nil, completion:?) // //// Self.GET(urlString: url, parameter: nil) { success , result , err in //// KMPrint("") //// } // } // // public class func GET(urlString: String, parameter: [String : String]? = nil, headers: [String : String]? = nil, callback:@escaping ((Bool, [String : Any]?, String?)->Void)) { //// var _urlString = "\(self.baseUrl)"+urlString // var _urlString = urlString // if let data = parameter, !data.isEmpty { // _urlString.append("?") // var i = 0 // for (key, value) in data { // _urlString.append("\(key)=\(value)") // if (data.count > 1 && i != data.count-1) { // _urlString.append("&") // } // i += 1 // } // } // // let url: URL = URL(string: _urlString)! // // let session = URLSession.shared // var request = URLRequest(url: url) // request.httpMethod = "GET" // request.setValue("application/json; charset=UTF-8", forHTTPHeaderField: "Content-Type") // if let _headers = headers { // for (key, value) in _headers { // request.setValue(value, forHTTPHeaderField: key) // } // } // request.timeoutInterval = 60.0 // session.configuration.timeoutIntervalForRequest = 30.0 // // let task: URLSessionDataTask = session.dataTask(with: request) { data , response, error in // DispatchQueue.main.async { // if let _ = error { // callback(false, nil, error.debugDescription) // return // } // guard let _data = data else { // callback(false, nil, error.debugDescription) // return // } // if let result = self.JsonDataParse(data: _data) { //// let resultMap = KMRequestResultModel(dict: result) //// var dataDict: [String : Any] = [:] //// if let data = resultMap.data as? [String : Any] { //// dataDict = data //// } else { //// if let dataArray = resultMap.data as? [Any] { //// var i = 0 //// for dict in dataArray { //// dataDict["\(i)"] = dict //// i += 1 //// } //// } //// } //// //// callback(resultMap.isSuccess(), dataDict, error.debugDescription) //// return // } //// callback(false, nil, error.debugDescription) // } // } // task.resume() // } // // private class func JsonDataParse(data: Data) -> Dictionary? { // let result = try?JSONSerialization.jsonObject(with: data, options: .mutableContainers) // return result as? Dictionary // } // // @objc func closeAction() { // self.trackEvent_free(eventName: "PUW_3", params: ["PUW_Btn" : "WinBackPuw_Cancel_Click"], platform: .firebase) // // window?.close() // } // // override func interfaceThemeDidChanged(_ appearance: NSAppearance.Name) { // super.interfaceThemeDidChanged(appearance) // // KMMainThreadExecute { // if KMAppearance.isDarkMode() { // self.titleLabel.textColor = .white // // let attri = NSMutableAttributedString(string: NSLocalizedString("Special Offer - ", comment: ""), attributes: [.font : NSFont.SFProTextRegularFont(32), .foregroundColor : NSColor.white]) // attri.append(.init(string: self.displayPriceString_, attributes: [.font : NSFont.SFProTextRegularFont(32), .foregroundColor : NSColor(hex: "#FD7272")])) // attri.append(.init(string: self.origialPrice_, attributes: [.font : NSFont.SFProTextRegularFont(24), .foregroundColor : NSColor(hex: "#7E7F85"), .strikethroughStyle : NSUnderlineStyle.single.rawValue])) // let style = NSMutableParagraphStyle() // style.alignment = .center // attri.addAttribute(.paragraphStyle, value: style, range: NSMakeRange(0, attri.length)) // self.subTitleLabel.attributedStringValue = attri // // self.despBox.fillColor = NSColor.white.withAlphaComponent(0.15) // self.despView_.titleLabel.textColor = .white // // let despAttri = NSMutableAttributedString(string: NSLocalizedString("First 6 months", comment: "")+" ", attributes: [.font : NSFont.SFProTextRegularFont(14), .foregroundColor : NSColor.white]) // despAttri.append(.init(string: self.displayPriceString_, attributes: [.font : NSFont.SFProTextRegularFont(14), .foregroundColor : NSColor(hex: "#227AFF")])) // let string = ", " + String(format: NSLocalizedString("then %@ for 6 months.", comment: ""), self.origialPrice_) // despAttri.append(.init(string: string, attributes: [.font : NSFont.SFProTextRegularFont(14), .foregroundColor : NSColor.white])) // self.despView_.subTitleLabel.attributedStringValue = despAttri // // self.despView_.hLine.layer?.backgroundColor = NSColor.white.withAlphaComponent(0.15).cgColor // // self.despView_.tipLabel.textColor = NSColor(hex: "#C8C9CC") // } else { // self.titleLabel.textColor = NSColor(hex: "#0E1114") // // let attri = NSMutableAttributedString(string: NSLocalizedString("Special Offer - ", comment: ""), attributes: [.font : NSFont.SFProTextRegularFont(32), .foregroundColor : NSColor(hex: "#000150")]) // attri.append(.init(string: self.displayPriceString_, attributes: [.font : NSFont.SFProTextRegularFont(32), .foregroundColor : NSColor(hex: "#FD7272")])) // attri.append(.init(string: self.origialPrice_, attributes: [.font : NSFont.SFProTextRegularFont(24), .foregroundColor : NSColor(hex: "#757780"), .strikethroughStyle : NSUnderlineStyle.single.rawValue])) // let style = NSMutableParagraphStyle() // style.alignment = .center // attri.addAttribute(.paragraphStyle, value: style, range: NSMakeRange(0, attri.length)) // self.subTitleLabel.attributedStringValue = attri // // self.despBox.fillColor = .white // self.despView_.titleLabel.textColor = NSColor(hex: "#0E1114") // // let despAttri = NSMutableAttributedString(string: NSLocalizedString("First 6 months", comment: "")+" ", attributes: [.font : NSFont.SFProTextRegularFont(14), .foregroundColor : NSColor(hex: "#000150")]) // despAttri.append(.init(string: self.displayPriceString_, attributes: [.font : NSFont.SFProTextRegularFont(14), .foregroundColor : NSColor(hex: "#4982E6")])) // let string = ", " + String(format: NSLocalizedString("then %@ for 6 months.", comment: ""), self.origialPrice_) // despAttri.append(.init(string: string, attributes: [.font : NSFont.SFProTextRegularFont(14), .foregroundColor : NSColor(hex: "#000150")])) // self.despView_.subTitleLabel.attributedStringValue = despAttri // // self.despView_.hLine.layer?.backgroundColor = NSColor.black.withAlphaComponent(0.15).cgColor // // self.despView_.tipLabel.textColor = NSColor(hex: "#757780") // } // // self.buttonView_.backgroundView.colors = [NSColor(hex: "#F8965A"), NSColor(hex: "#FD7171")] // // self.buttonView_.button.title = NSLocalizedString("Get Special Offer - Advanced 6 Mos", comment: "") // self.buttonView_.button.setTitleColor(.white) // } // } // // // MARK: - Private Methods // // private func _showCenter(animate: Bool){ // guard let screenFrame = NSScreen.main?.frame else { // return // } // guard let win = self.window else { // return // } // // var frame = win.frame // frame.origin.y = (screenFrame.size.height-frame.size.height)*0.5 // frame.origin.x = (screenFrame.size.width-frame.size.width)*0.5 // win.setFrame(frame, display: true, animate: animate) // } // // // MARK: - Private Methods // // private func _saveRecord() { // let lastShowTime = KMDataManager.ud_double(forKey: lastShowTimeKey_) // if lastShowTime <= 0 { // let cnt = KMDataManager.ud_integer(forKey: showCountKey_) // KMDataManager.ud_set(cnt+1, forKey: showCountKey_) // // let date = Date().timeIntervalSince1970 // KMDataManager.ud_set(date, forKey: lastShowTimeKey_) // return // } // // let date = Date(timeIntervalSince1970: lastShowTime) // // let calendar = Calendar.current // let unit: Set = [.day,.month,.year] // let nowComps = calendar.dateComponents(unit, from: Date()) // let selfCmps = calendar.dateComponents(unit, from: date) // // let theYear = selfCmps.year ?? 0 // let theMonth = selfCmps.month ?? 0 // let theDay = selfCmps.day ?? 0 // let otherYear = nowComps.year ?? 0 // let otherMonth = nowComps.month ?? 0 // let otherDay = nowComps.day ?? 0 // // if otherYear > theYear || otherMonth > theMonth { // let cnt = KMDataManager.ud_integer(forKey: showCountKey_) // KMDataManager.ud_set(cnt+1, forKey: showCountKey_) // // let date = Date().timeIntervalSince1970 // KMDataManager.ud_set(date, forKey: lastShowTimeKey_) // return // } // // if otherDay - theDay >= 1 { // let cnt = KMDataManager.ud_integer(forKey: showCountKey_) // KMDataManager.ud_set(cnt+1, forKey: showCountKey_) // // let date = Date().timeIntervalSince1970 // KMDataManager.ud_set(date, forKey: lastShowTimeKey_) // return // } // } // // private func _fetchOrigialPrice() -> String? { // return IAPProductsManager.default().fourDevicesAllAccessPackNew6Months_lite?.price() // } // // private func _selectOffer(offerId: String) { // offerId_ = offerId // if #available(macOS 12.0, *) { // winbackOffers(productId: "com.pdfreaderpro.mac_free.member.all_access_pack_advanced_6months.001") { offsers in // for offse in offsers { // let data = offse.id // if data == offerId { // self.displayPriceString_ = offse.displayPrice // // self.origialPrice_ = self._fetchOrigialPrice() ?? "" // // self.interfaceThemeDidChanged(self.window?.appearance?.name ?? .aqua) // } // } // } // } else { // // } // } // // private func _showAlert(message: String) { // KMMainThreadExecute { // let alert = NSAlert() // alert.alertStyle = .critical // alert.messageText = message // alert.addButton(withTitle: NSLocalizedString("OK", comment: "")) // alert.runModal() // } // } // // private func _beginLoading() { // self.window?.contentView?.beginLoading() // } // // private func _endLoading() { // self.window?.contentView?.endLoading() // } // // // MARK: - Public Methods // // public func openWindow() { //// self.showWindow(nil) // // if #available(macOS 12.0, *) { // winbackOffers(productId: "com.pdfreaderpro.mac_free.member.all_access_pack_advanced_6months.001") { [weak self] offers in // if offers.isEmpty { // 商品没有配置 Win Back 优惠卷 // self?.window?.setIsVisible(false) // self?.window?.close() // } else { // if let data = self?.offerId_, data.isEmpty == false { // // no things // } else { // self?.showWindow(nil) // // self?.window?.setIsVisible(false) // self?.window?.close() // } // } // } // } else { // window?.setIsVisible(false) // window?.close() // } // } // // public func needShow() -> Bool { // if #available(macOS 15.0, iOS 18.0, *) { // if KMDataManager.ud_integer(forKey: showCountKey_) >= 3 { //#if DEBUG // return true //#else // return false //#endif // } // // let lastShowTime = KMDataManager.ud_double(forKey: lastShowTimeKey_) // if lastShowTime > 0 { // let date = Date(timeIntervalSince1970: lastShowTime) // if date.isToday() { //#if DEBUG //#else // return false //#endif // } // } // // if KMNewUserGiftManager.default.loginProgressState == .none || KMNewUserGiftManager.default.fetchReceiptProgressState == .none { // return false // } // // let member = KMMemberInfo.shared //// if member.isLogin { //// if member.is_advanced() && member.is_subscribe() && (member.is_year() || member.is_half_year()) { //// return false //// } //// } // if member.isMemberAllFunction { // 有本地或账号权益 // return false // } // // return true // } // return false // } // // public func clearRecord() { // KMDataManager.ud_set(0, forKey: showCountKey_) // KMDataManager.ud_set(0, forKey: lastShowTimeKey_) // } // // @available(macOS 12.0, *) // public func winbackOffers(productId: String?, callback: (([Product.SubscriptionOffer])->Void)?) { // if #available(macOS 15.0, iOS 18.0, *) { // guard let theProductId = productId else { // callback?([]) // return // } // // Task { // let products = try await Product.products(for: [theProductId]) // guard let product = products.first else { // callback?([]) // return // } // // guard let subscriptionInfo = product.subscription else { // callback?([]) // return // } // // callback?(subscriptionInfo.winBackOffers) // } // } else { // callback?([]) // } // } // // public func purchase() { // Task { @MainActor in // // 加载产品 // if #available(macOS 15.0, *) { // let products = try? await Product.products(for: ["com.pdfreaderpro.mac_free.member.all_access_pack_advanced_6months.001"]) // guard let product = products?.first else { // _showAlert(message: "未找到指定的产品") // return // } // // // 确保产品为订阅类型 // guard let subscriptionInfo = product.subscription else { // _showAlert(message: "该产品不是订阅类型") // return // } // // // 查找可用的 Win-Back Offer // KMPrint("product:\(product)") // KMPrint("subscriptionInfo.winBackOffers:\(subscriptionInfo.winBackOffers)") // let offers = subscriptionInfo.winBackOffers // // var off: Product.SubscriptionOffer? // for offer in offers { // if self.offerId_ == offer.id { // off = offer // break // } // } // // guard let winBackOffer = off else { // KMPrint("没有找到适合用户的 Win-Back Offer") // _showAlert(message: "No Offer") // return // } // // // 使用 Win-Back Offer 创建购买选项 // let purchaseOption = Product.PurchaseOption.winBackOffer(winBackOffer) // // self._beginLoading() // // 发起购买 // let purchaseResult = try await product.purchase(options: [purchaseOption]) // switch purchaseResult { // case .success(let verificationResult): // self._endLoading() // // switch verificationResult { // case .verified(let transaction): // KMPrint("购买成功:\(transaction.id)") // await transaction.finish() // // DispatchQueue.main.asyncAfter(deadline: .now()+1) { // self.window?.close() // // let man = IAPProductsManager.default() // man?.winbackIAPPurchased(withProdcutId: transaction.productID, transactionId: "\(transaction.id)") // } // // case .unverified(_, let error): // KMPrint("验证失败:\(error)") // } // case .userCancelled: // KMPrint("用户取消了购买") // self._endLoading() // case .pending: // KMPrint("购买失败") // @unknown default: // KMPrint("购买失败") // } // } // } // } //} // //// MARK: - NSWindowDelegate // //extension KMWinBackWindowController: NSWindowDelegate { // func windowDidResize(_ notification: Notification) { // guard let data = window?.isEqual(to: notification.object), data == true else { // return // } // backgroundIv.image?.size = window?.frame.size ?? NSMakeSize(520, 540) // } //}