事务在finishTransaction之后返回:已被调用

Cra*_*hon 23 iphone in-app-purchase

我正在使用应用程序内购买iPhone应用程序.我有一个充当SKProductsRequestDelegate和的类SKPaymentTransactionObserver,并且它在iTunes上当前发布的版本中都运行良好.

但是,在最近添加一个新的非消耗品并在Sandbox环境中进行测试之后,我现在遇到了一个奇怪的问题.每次我启动应用程序时,我昨天的购买重新出现在传递给我的交易列表中paymentQueue:updatedTransactions:,尽管事实上我已经打过电话[[SKPaymentQueue defaultQueue] finishTransaction:transaction](好几次).这是亡灵!

在我的paymentQueue:updatedTransactions:实施中,我有:

for (SKPaymentTransaction* transaction in transactions) 
    switch (transaction.transactionState)
    {
        case SKPaymentTransactionStatePurchased:
        case SKPaymentTransactionStateRestored:
        {
            ....
                DDLog(@"Transaction for %@ occurred originally on %@.", transaction.payment.productIdentifier, transaction.originalTransaction.transactionDate);
                ....
Run Code Online (Sandbox Code Playgroud)

然后我处理购买,下载用户内容,最后,在另一种方法中,执行以下操作:

for (SKPaymentTransaction* transaction in [[SKPaymentQueue defaultQueue] transactions])         
            if (([transaction.payment.productIdentifier isEqualToString:theParser.currentProductID]) &&
                 ((transaction.transactionState==SKPaymentTransactionStatePurchased) || (transaction.transactionState==SKPaymentTransactionStateRestored))
               )
            {
                DDLog(@"[[ Transaction will finish: product ID = %@; date = %@ ]]", transaction.payment.productIdentifier, transaction.transactionDate);
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
            }
Run Code Online (Sandbox Code Playgroud)

您可能已经注意到,为了简单起见,我并没有坚持原始的事务对象,并且稍后从调用中找到它相对容易[[SKPaymentQueue defaultQueue] transactions].无论如何,我确实看到了预期的输出; 交易已完成,并且与产品ID和原始交易日期完全匹配.但是,下次我运行应用程序时,整个事情重新开始!就像iTunes Store从未通知交易已完成或拒绝承认.

Cra*_*hon 17

在开发人员论坛中也提出了这个问题,一般的结论是它在iPhone OS 4.0中处理事务的差异.只有在收到已完成交易的通知和呼叫finishTransaction支付队列之间存在显着延迟时,才会出现此问题.最后我们找不到理想的解决方案,但我们做的是:

  1. 一旦事务到达,处理它并在处理成功时在用户首选项中记录值.

  2. 下次该事务出现在队列中时(可能直到下次启动应用程序时)才会立即调用finishTransaction它.

我们的产品是"非消耗品",因此足以检查所支付的产品是否有效且无错误,以安全地忽略来自iTunes的任何"不死"重复交易.对于消费品,需要保存有关购买的更多信息,例如原始付款日期,以确保未来的交易通知可以与已经处理的购买相匹配.


alp*_*r_k 6

这个问题也发生在我身上,我找到了解决方案.在类似的情况下,这可能对你有帮助

finishTransaction立即打电话,但下次当我尝试买东西时,之前的产品也随之而来!所以第一次,我买了一个产品.但第二次,我也买了第二个产品和第一个产品.

我发现我SKPaymentTransactionObserver多次添加!这导致了问题,多次购买.

当过程结束时,我的意思是当你打电话时finishTransaction,在此之后,打电话: [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];

这将清除交易并删除观察者.所以下次,你不会多次购买.


Dav*_*uma 5

我没有深入研究过这个,但是我看到我在iOS 4中对finishTransaction的调用可靠地失败了.在预感中,我在dispatch_async调用中调用了finishTransaction并且问题消失了.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
  [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
});
Run Code Online (Sandbox Code Playgroud)

也许一个突出的问题是我在一个块中调用了finishTransaction,它最终在网络调用我的服务器之后运行.