9 storekit in-app-purchase ios skpaymenttransaction
我们有一个应用程序被苹果拒绝了几次,因为它无法完成自动续订 IAP 购买,并且如果尝试也无法恢复。我们最终通过添加一些额外的日志记录来缩小错误范围,并Payment added for transaction already in the SKPaymentQueue: ...在日志中注意到。
在尝试重现时,我们启动了一段时间没有使用的手机,并注意到队列中有27 笔SKPaymentTransactionState.purchased相同购买的交易,全部处于状态。我们SKPaymentTransactionObserver会收到这些交易的通知,并且会进行拜访finishTransaction。我假设有这么多交易,因为我们有每月订阅,沙盒中每 5 分钟自动续订一次,并且我们一直在另一部手机上使用相同的 App Store 帐户额外购买同一个 IAP - 所以现在,该手机将收到所有更新的通知。
奇怪的是,即使我们调用finishTransaction这些交易,它们似乎仍未完成,这就是为什么我们在控制台中看到“为已在队列中的交易添加的付款”消息。
因此,为了调试这个,我实现了paymentQueue(_:removedTransactions:)of SKPaymentTransactionObserver,并注意到,即使我们调用了finishTransaction如此多的事务,我们也只会看到一个被删除 - 而且似乎如果我们在应用程序中停留很长时间,只是什么也不做,那么更多的事务就会被删除。历时10多分钟。
在我的沮丧中,我继续做了这样的事情
public func paymentQueue(_ queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) {
let remainingTransactions = queue.transactions
let hasRemainingTransactions = !remainingTransactions.isEmpty
if hasRemainingTransactions {
paymentQueue(queue, updatedTransactions: remainingTransactions)
}
}
Run Code Online (Sandbox Code Playgroud)
这当然是非常恶心的,但你难道不知道,对于 n 笔交易中的每笔交易,它们都被一笔一笔地删除——一次只删除一笔。
所以我的第一个想法是,嗯,这在现实世界中可能不太可能发生,因为你一次又一次地购买、更新得如此之快等,所以也许 SDK 并不期望一次完成这么多交易?我尝试了一些不那么恶心的东西,并paymentQueue(_:updatedTransactions:)从这样的地方改变了我们的东西
public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
switch transaction.transactionState {
case .purchased:
SKPaymentQueue.default().finishTransaction(transaction)
case .restored:
SKPaymentQueue.default().finishTransaction(transaction)
case .failed:
SKPaymentQueue.default().finishTransaction(transaction)
default:
break
}
}
}
Run Code Online (Sandbox Code Playgroud)
对于这样的事情
public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
DispatchQueue.main.async {
switch transaction.transactionState {
case .purchased:
SKPaymentQueue.default().finishTransaction(transaction)
case .restored:
SKPaymentQueue.default().finishTransaction(transaction)
case .failed:
SKPaymentQueue.default().finishTransaction(transaction)
default:
break
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
相同的代码只是每个事务处理而不是在同一个运行循环中。这里发生的事情是paymentQueue(_:removedTransactions:)连续两次调用 1 个已删除的事务,然后在这次测试中批量运行剩余的 5 个事务。所以这个“修复”/解决了这个问题 - 但为什么呢?
那么这里发生了什么?这是沙盒中完成交易所需时间的怪癖吗?难道我们不希望在运行循环的同一次运行中完成所有这些吗?我是否完全错过了一些核心概念?
从环境角度来看,该应用程序是在 Xcode 11.3.1 中构建的,问题在 iOS 13.6.1 和其他 iOS 13 版本上最容易重现,似乎会发生,但在 iOS 12.0 上发生的次数要少得多,在 iOS 14 beta 上还没有看到它发生。iOS SDK 目标是 11.0。我们只有一个 IAP,即按月自动续订。
虽然这个解决办法似乎解决了这个问题,但我们一直处于与苹果的拒绝循环中,并且希望在向他们扔更多版本以希望某些东西能够坚持之前,对正在发生的事情有更扎实的理解或推理。
我相信我有办法解决这个问题。我遇到了完全相同的问题,Apple 一直拒绝我的应用程序,而我在沙箱环境中已经进行了 32 笔交易;)
我在其他地方看到你可以实现这个方法:“removedTransactions”。在这种方法中,我发现它实际上删除了所有 32 个事务,但一次删除一个,而且速度非常慢,比如 1 秒。每笔交易。如果我在新购买完成之前没有等待它,那么它总是会卡住并且永远不会正确地开始我的新购买!这是方法和我的日志:
func paymentQueue(_ queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) {
DLog("Removed transactions: \(transactions.count)")
DLog("Unfinished transaction: \(queue.transactions.count)")
}
Run Code Online (Sandbox Code Playgroud)
因此,一旦我弄清楚了这一点,我就知道我只需要等到队列空了就可以开始新的购买。这是我使用的代码:
DLog("Initiating purchase...")
while self.paymentQueue.transactions.count > 0 {
DLog("Still busy removing previous transactions: \(self.paymentQueue.transactions.count)")
sleep(2)
}
DLog("Payment queue is empty, let's buy!")
self.payment = SKPayment(product: product)
self.paymentQueue.add(self.payment!)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1854 次 |
| 最近记录: |