diff --git a/ThimraTV/Base/Networking/API/SPWalletAPI.swift b/ThimraTV/Base/Networking/API/SPWalletAPI.swift index 047f6a9..eafe9a7 100644 --- a/ThimraTV/Base/Networking/API/SPWalletAPI.swift +++ b/ThimraTV/Base/Networking/API/SPWalletAPI.swift @@ -14,9 +14,71 @@ class SPWalletAPI: NSObject { } ///获取支付模版 - static func requestPayTemplate(completer: ((_ model: SPPayTemplateModel?) -> Void)?) { + static func requestPayTemplate(isLoding: Bool = false, isToast: Bool = true, completer: ((_ model: SPPayTemplateModel?) -> Void)?) { + + if isLoding { + SPHUD.show() + } + + _requestPayTemplate(isToast: isToast) { model in + guard let model = model else { + if isLoding { + SPHUD.dismiss() + } + completer?(nil) + return + } + var productIdArr: [String] = [] + model.list_sub_vip?.forEach { item in + productIdArr.append(SPIAPManager.manager.getProductId(templateId: item.ios_template_id) ?? "") + } + model.list_coins?.forEach { item in + productIdArr.append(SPIAPManager.manager.getProductId(templateId: item.ios_template_id) ?? "") + } + + SPIAPManager.manager.requestProductList(productIdArr: productIdArr) { products in + if isLoding { + SPHUD.dismiss() + } + + var newCoinList: [SPPayTemplateItem] = [] + var newVipList: [SPPayTemplateItem] = [] + + model.list_coins?.forEach { item in + let productId = SPIAPManager.manager.getProductId(templateId: item.ios_template_id) ?? "" + for product in products { + if productId == product.productIdentifier { + item.price = product.price.stringValue + item.currency = product.priceLocale.currencySymbol + newCoinList.append(item) + break + } + } + } + model.list_sub_vip?.forEach { item in + let productId = SPIAPManager.manager.getProductId(templateId: item.ios_template_id) ?? "" + for product in products { + if productId == product.productIdentifier { + item.price = product.price.stringValue + item.currency = product.priceLocale.currencySymbol + newVipList.append(item) + break + } + } + } + model.list_coins = newCoinList + model.list_sub_vip = newVipList + + completer?(model) + } + + } + } + + private static func _requestPayTemplate(isToast: Bool = true, completer: ((_ model: SPPayTemplateModel?) -> Void)?) { var param = SPNetworkParameters(path: "/paySettingsV3") param.method = .get + param.isToast = isToast SPNetwork.request(parameters: param) { (response: SPNetworkResponse) in completer?(response.data) diff --git a/ThimraTV/Libs/SPIAPManager/SPIAPManager.swift b/ThimraTV/Libs/SPIAPManager/SPIAPManager.swift index b633730..0345fba 100644 --- a/ThimraTV/Libs/SPIAPManager/SPIAPManager.swift +++ b/ThimraTV/Libs/SPIAPManager/SPIAPManager.swift @@ -6,6 +6,7 @@ // import UIKit +import StoreKit class SPIAPManager: NSObject { typealias CompletionHandler = ((_ finish: Bool) -> Void) @@ -18,6 +19,8 @@ class SPIAPManager: NSObject { ///成功回调 private var completionHandler: CompletionHandler? + private var productListHandler: ((_ products: [SKProduct]) -> Void)? + private lazy var iapManager: JXIAPManager = { let manager = JXIAPManager() manager.delegate = self @@ -119,6 +122,17 @@ class SPIAPManager: NSObject { } } + + func requestProductList(productIdArr: [String], completer: ((_ products: [SKProduct]) -> Void)?) { + self.productListHandler = completer + self.iapManager.requestProductList(productIdArr: productIdArr) + } + + + func getProductId(templateId: String?) -> String? { + guard let templateId = templateId else { return nil } + return SPIAPManager.IAPPrefix + templateId + } } //MARK: -------------- JXIAPManagerDelegate -------------- @@ -182,6 +196,13 @@ extension SPIAPManager: JXIAPManagerDelegate { self.completionHandler?(false) } + func jx_iapPayGotProducts(products: [SKProduct]) { + + self.productListHandler?(products) + + self.productListHandler = nil + } + } extension SPIAPManager { diff --git a/ThimraTV/Thirdparty/JXIAPManager/JXIAPManager.swift b/ThimraTV/Thirdparty/JXIAPManager/JXIAPManager.swift index 1ceb6ae..8094f87 100644 --- a/ThimraTV/Thirdparty/JXIAPManager/JXIAPManager.swift +++ b/ThimraTV/Thirdparty/JXIAPManager/JXIAPManager.swift @@ -10,7 +10,7 @@ import StoreKit @objc protocol JXIAPManagerDelegate { /// 获取到可购买商品列表 - @objc optional func jx_iapPayGotProducts(productIds: [String]) + @objc optional func jx_iapPayGotProducts(products: [SKProduct]) /// 购买成功 @objc optional func jx_iapPaySuccess(productId: String, receipt: String, transactionIdentifier: String?) /// 购买失败 @@ -34,19 +34,29 @@ import StoreKit case cancelled ///没有商品 case noProduct - } class JXIAPManager: NSObject { + enum OperationType { + case idle + case buy + case request + } + static let manager: JXIAPManager = JXIAPManager() weak var delegate: JXIAPManagerDelegate? + ///当前操作状态 + private var operationType = OperationType.idle + private var payment: SKPayment? private var product: SKProduct? private var productId: String? + + private var discount: SKPaymentDiscount? private var orderId: String? private var applicationUsername: String? { get { @@ -80,10 +90,47 @@ class JXIAPManager: NSObject { SKPaymentQueue.default().add(self) } - func start(productId: String, orderId: String) { + func showCodeRedemption() { + SKPaymentQueue.default().presentCodeRedemptionSheet() + } + + func requestProductList(productIdArr: [String]) { + guard self.operationType == .idle else { return } + self.operationType = .request + + let set = Set(productIdArr) + let productsRequest = SKProductsRequest(productIdentifiers: set) + productsRequest.delegate = self + productsRequest.start() + } + +// ///发起购买 +// func buyProduct(product: SKProduct, orderId: String, discount: SKPaymentDiscount? = nil) { +// guard self.operationType == .idle else { return } +// self.operationType = .buy +// +// self.product = product +// self.orderId = orderId +// +// // 要购买商品,开个小票 +// let payment = SKMutablePayment(product: product) +// payment.applicationUsername = applicationUsername +// if let discount = discount { +// payment.paymentDiscount = discount +// } +// +// // 去收银台排队,准备购买 +// SKPaymentQueue.default().add(payment) +// } + + func start(productId: String, orderId: String, discount: SKPaymentDiscount? = nil) { + guard self.operationType == .idle else { return } + self.operationType = .buy + self.product = nil self.productId = productId self.orderId = orderId + self.discount = discount let set = Set([productId]) let productsRequest = SKProductsRequest(productIdentifiers: set) @@ -98,9 +145,13 @@ class JXIAPManager: NSObject { // 要购买商品,开个小票 let payment = SKMutablePayment(product: product) payment.applicationUsername = applicationUsername - spLog(message: payment.applicationUsername) + if let discount = self.discount { + payment.paymentDiscount = discount + self.discount = nil + } self.payment = payment + // 去收银台排队,准备购买 SKPaymentQueue.default().add(payment) } @@ -110,18 +161,27 @@ class JXIAPManager: NSObject { //MARK: -------------- SKProductsRequestDelegate -------------- extension JXIAPManager: SKProductsRequestDelegate { func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { - guard let product = response.products.first else { + if self.operationType == .request { DispatchQueue.main.async { - if let productId = self.productId { - self.productId = nil - self.delegate?.jx_iapPayFailed?(productId: productId, code: .noProduct) - } + self.delegate?.jx_iapPayGotProducts?(products: response.products) } - return + self.operationType = .idle + } else if self.operationType == .buy { + + guard let product = response.products.first else { + DispatchQueue.main.async { + if let productId = self.productId { + self.productId = nil + self.delegate?.jx_iapPayFailed?(productId: productId, code: .noProduct) + } + } + return + } + self.product = product + + self.buyProduct() } - self.product = product - self.buyProduct() } } @@ -131,7 +191,6 @@ extension JXIAPManager: SKPaymentTransactionObserver { func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { for transaction in transactions { - spLog(message: "transactionState = \(transaction.transactionState)") switch transaction.transactionState { case .purchased: DispatchQueue.main.async { @@ -171,33 +230,21 @@ extension JXIAPManager: SKPaymentTransactionObserver { extension JXIAPManager { private func completeTransaction(transaction: SKPaymentTransaction) { - //自动续费 -// if let _ = transaction.original, transaction.payment.applicationUsername == nil { -// return -// } - //重新开通自动续费 -// if let _ = transaction.original, transaction.payment.applicationUsername != nil { -// self.delegate?.jx_iapPayFailed?(productId: productId, code: .unknown) -// return -// } - - spLog(message: "transactionDate = \(String(describing: transaction.transactionDate))") - spLog(message: "nowDate = \(Date())") - spLog(message: "productIdentifier = \(transaction.payment.productIdentifier)") - - guard let productId = self.productId, productId == transaction.payment.productIdentifier else { return } - self.productId = nil - guard let receiptURL = Bundle.main.appStoreReceiptURL else { return } let receiptData = NSData(contentsOf: receiptURL) guard let encodeStr = receiptData?.base64EncodedString(options: .endLineWithLineFeed) else { return } guard let transactionIdentifier = transaction.transactionIdentifier else { return } + + guard let productId = self.productId, productId == transaction.payment.productIdentifier else { return } + self.operationType = .idle + self.productId = nil self.delegate?.jx_iapPaySuccess?(productId: productId, receipt: encodeStr, transactionIdentifier: transactionIdentifier) } private func failedTransaction(transaction: SKPaymentTransaction) { + self.operationType = .idle let error = transaction.error as? SKError guard let productId = self.productId else { return } self.productId = nil