在处理恢复购买时如何处理旧交易?



我目前正在与沙盒用户一起开发和测试我的应用程序。即使事务已完成,当我尝试Restore Purchases时,我从队列中获取多达 32 个旧事务。

从本质上讲,我想像Your purchase is being restored. Upon completion this dialog will close.一样发出警报,并在完成后将其关闭。

private func showRestoreInProgressAlert() {
let alert = UIAlertController(title: "Restoring Purchase", message: "Your purchase history is being restored. Upon completion this dialog will close.", preferredStyle: .alert)
present(alert, animated: true, completion: nil)
NotificationCenter.default.addObserver(self, selector: #selector(dismissRestoreInProgressAlert(notification:)), name: SubscriptionService.restoreSuccessfulNotification, object: nil)
}

您可能会从下面SKPaymentTransactionObserver中认出这种方法。发送通知.restoreSuccessfulNotification后,警报将按预期消除。但由于队列中有 32 个事务,弹出窗口不断出现和消失 32 次。

func handleRestoredState(for transaction: SKPaymentTransaction, in queue: SKPaymentQueue) {
print("Purchase restored for product id: (transaction.payment.productIdentifier)")
queue.finishTransaction(transaction)
SubscriptionService.shared.uploadReceipt { (success) in
DispatchQueue.main.async {
NotificationCenter.default.post(name: SubscriptionService.restoreSuccessfulNotification, object: nil)
}
}
}

func paymentQueue(_ queue: SKPaymentQueue,
updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
switch transaction.transactionState {
case .purchasing:
handlePurchasingState(for: transaction, in: queue)
case .purchased:
handlePurchasedState(for: transaction, in: queue)
case .restored:
handleRestoredState(for: transaction, in: queue)
case .failed:
handleFailedState(for: transaction, in: queue)
case .deferred:
handleDeferredState(for: transaction, in: queue)
}
}
}

我已经像这样完成了handlePurchasedStatehandleRestoredState的交易:

queue.finishTransaction(transaction)

那么,为什么每当我单击恢复购买时,队列中仍然有这么多旧交易?

更新

这确实可能是沙盒的问题。

我试图做一个计数,但这没有帮助,仅仅是因为并非所有这些交易似乎都是可恢复的。

我做了"硬重置":

for transaction: AnyObject in SKPaymentQueue.default().transactions {
guard let currentTransaction: SKPaymentTransaction = transaction as? SKPaymentTransaction else {return}
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
}

现在看来,交易正在慢慢减少到零,这意味着沙盒现在正在失去它们。

为什么SKPaymentQueue.default().finishTransaction()在工作,而queue.finishTransaction()却没有?为了安全起见,我应该重构我的代码以使用SKPaymentQueue.default().finishTransaction()而不是安全起见吗?或者这只是IAP沙盒糟糕的一天?

恢复会将所有购买重新交付给您的交易观察者代表。这是预期的行为。

但是,以您想要的方式显示警报非常简单。

  1. 当用户启动还原操作时,显示警报。

  2. 然后,还原所有项后,将调用paymentQueueRestoreCompletedTransactionsFinished委托方法。在此方法中,可以消除警报。

每次请求还原时,将返回所有活动订阅和所有非消耗性项目(由当前用户购买)。

想一想,如果它们在您完成后不再归还,您将如何恢复?

显然,您的应用可以为用户提供多个活动订阅和/或非消耗品。为避免收到多个警报,应将所有 StoreKit 还原回调合并到一个(或几个)用户通知中。

这在你的情况下有意义吗?

最新更新