我正在为iPhone应用程序使用应用程序内购买。我有一个充当SKProductsRequestDelegateSKPaymentTransactionObserver的类,并且在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);
                ....

然后,我处理购买,下载用户内容,最后用另一种方法执行此操作:
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];
            }

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

最佳答案

在开发人员论坛中也提出了这个问题,并且总体结论是,这归结于iPhone OS 4.0中事务处理的不同。仅在收到已完成交易的通知与在支付队列上调用finishTransaction之间存在明显的延迟时,才出现此问题。最终,我们没有找到理想的解决方案,但我们要做的是:

  • 交易到达后,立即进行处理,如果处理成功,则在用户首选项中记录一个值。
  • 下一次该事务出现在队列中(可能要等到下次启动该应用程序时才出现),立即在其上调用finishTransaction

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

    09-30 11:56