ios SKPaymentQueue finishTransactions未从队列中删除事务

nue99wik  于 2023-06-25  发布在  iOS
关注(0)|答案(3)|浏览(200)

updatedTransactions:委托回调使用几天前的旧事务触发。我试着在它们上调用finishTransactions,但是当我启动应用程序时,相同的交易仍然存在(检查了transactionIdentifier)一遍又一遍。
我不能再买新东西了。当进行新的购买时,其中一个旧交易将以SKPaymentTransactionStatePurchased状态返回,但因为它之前已经成功,所以我从Apple收到一个错误:* “此应用内购买已被购买。它将免费恢复。【环境:沙盒]"*
Error message
如何从事务队列中正确删除事务?

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions {

    // Getting called with old, already finished transactions

    for (SKPaymentTransaction *transaction in transactions) {
        switch (transaction.transactionState) {
            case SKPaymentTransactionStatePurchasing:
                break;
            case SKPaymentTransactionStateDeferred:
                // ...
                break;
            case SKPaymentTransactionStateFailed:
                // ...
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                break;
            case SKPaymentTransactionStatePurchased:
                // validate receipt first
                // then finish transaction
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                break;
            case SKPaymentTransactionStateRestored:
                // ...
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                break;
            default:
                break;
        }
    }
}

编辑:

我确认了finishTransactions没有将它们从队列中删除。

NSArray<SKPaymentTransaction *> *transactions = [[SKPaymentQueue defaultQueue] transactions];
NSLog(@"BEFORE transactions = %@", transactions);
for (SKPaymentTransaction *txn in transactions) {
    [[SKPaymentQueue defaultQueue] finishTransaction:txn];
}
transactions = [[SKPaymentQueue defaultQueue] transactions];
NSLog(@"AFTER transactions = %@", transactions);

输出:

BEFORE transactions = (
    "<SKPaymentTransaction: 0x2802c8b10>",
    "<SKPaymentTransaction: 0x2802c8c60>",
    "<SKPaymentTransaction: 0x2802c8c40>",
    "<SKPaymentTransaction: 0x2802c8c20>",
    "<SKPaymentTransaction: 0x2802c8b00>"
)
AFTER transactions = (
    "<SKPaymentTransaction: 0x2802c8b10>",
    "<SKPaymentTransaction: 0x2802c8c60>",
    "<SKPaymentTransaction: 0x2802c8c40>",
    "<SKPaymentTransaction: 0x2802c8c20>",
    "<SKPaymentTransaction: 0x2802c8b00>"
)

编辑#2:

我在苹果开发者论坛上发现,这在过去48小时内影响了其他一些人。我认为这是苹果方面的一个问题。

我们通过我们的合作伙伴团队联系了Apple,并能够确认Apple的服务在此期间确实出现了故障,但问题已经解决。

atmip9wb

atmip9wb1#

finishTransaction:方法应该做你想要实现的。但是,您测试行为的方式并不正确,因为StoreKit paymentQueue:removedTransactions:中有另一个委托方法来获取已删除的事务。
finishTransaction:和实际移除之间可能存在少量延迟。因此,如果在finishTransaction:之后直接调用[[SKPaymentQueue defaultQueue] transactions],它仍然可以返回事务
我建议您使用delegate方法验证事务的删除。

apeeds0o

apeeds0o2#

首先,您需要将所有purchasedrestoredfailed事务标记为finished,而不仅仅是purchased事务。
要使用空事务队列重新开始,我建议您将以下行添加到商店组件或任何处理购买的地方的初始化代码中:

SKPaymentQueue.default().transactions.forEach({ SKPaymentQueue.default().finishTransaction($0) })

这会将所有当前打开的事务标记为已完成,并允许您使用空事务队列重新开始。

utugiqy6

utugiqy63#

可以在

extension StoreKitManager: SKPaymentTransactionObserver {
    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    
          SKPaymentQueue.default().transactions.forEach({
          SKPaymentQueue.default().finishTransaction($0)})
    }
    }

相关问题