jsdw_ios/QuickLocation/Manager/IAPManager/IAPManager.swift

82 lines
2.7 KiB
Swift

//
// IAPManager.swift
// QuickLocation
//
// Created by on 2026/7/3.
//
import StoreKit
import RxSwift
class IAPManager: NSObject {
static let shared = IAPManager()
private let disposeBag = DisposeBag()
private var currentGoodsId: String = ""
private var purchaseCompletion: ((Bool, String?) -> Void)?
func startObserving() {
SKPaymentQueue.default().add(self)
}
func purchase(goodsId: String, completion: @escaping (Bool, String?) -> Void) {
currentGoodsId = goodsId
purchaseCompletion = completion
let request = SKProductsRequest(productIdentifiers: [goodsId])
request.delegate = self
request.start()
}
}
// MARK: - SKProductsRequestDelegate
extension IAPManager: SKProductsRequestDelegate {
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
guard let product = response.products.first else {
purchaseCompletion?(false, "商品不可用")
return
}
SKPaymentQueue.default().add(SKPayment(product: product))
}
}
// MARK: - SKPaymentTransactionObserver
extension IAPManager: SKPaymentTransactionObserver {
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for tx in transactions {
switch tx.transactionState {
case .purchased:
verifyReceipt(transaction: tx)
case .failed:
queue.finishTransaction(tx)
let msg = tx.error?.localizedDescription ?? "支付失败"
purchaseCompletion?(false, msg)
default:
break
}
}
}
private func verifyReceipt(transaction: SKPaymentTransaction) {
guard let receiptURL = Bundle.main.appStoreReceiptURL,
let receiptData = try? Data(contentsOf: receiptURL) else {
SKPaymentQueue.default().finishTransaction(transaction)
purchaseCompletion?(false, "获取凭证失败")
return
}
let receipt = receiptData.base64EncodedString()
let txId = transaction.transactionIdentifier ?? ""
OrderService.appleNotify(
receipt: receipt,
productId: currentGoodsId,
transactionId: txId
).subscribe(onNext: { [weak self] _ in
SKPaymentQueue.default().finishTransaction(transaction)
self?.purchaseCompletion?(true, nil)
}, onError: { [weak self] error in
SKPaymentQueue.default().finishTransaction(transaction)
self?.purchaseCompletion?(false, error.localizedDescription)
}).disposed(by: disposeBag)
}
}