iOS“此应用内购买已购买”弹出窗口

9
我在我的iOS应用程序中遇到了一个问题:当我点击“购买”按钮以购买IAP产品时,会弹出一个窗口显示以下消息:

此应用内购买已经购买。它将免费恢复。

我以前从未遇到过这个弹出窗口,而且我的产品只是非自动续订的订阅,所以我想知道为什么在购买订阅时会出现这个消息。
当我点击确定关闭这个弹出窗口时,购买不会执行。
以下是我的代码:
for transaction in transactions {
        switch transaction.transactionState {

        case SKPaymentTransactionState.Purchased, SKPaymentTransactionState.Restored:
            print("Transaction completed successfully.")
            SKPaymentQueue.defaultQueue().finishTransaction(transaction)
            transactionInProgress = false
            // Sauvegarde le produit acheté
            savePurchasedProduct(transaction.transactionDate!);
            break

        case SKPaymentTransactionState.Failed:
            print("Transaction Failed");
            SKPaymentQueue.defaultQueue().finishTransaction(transaction)
            transactionInProgress = false
            break

        default:
            break
        }
    }

我有同样的问题。在这里修复了:https://dev59.com/RpHea4cB1Zd3GeqPlCTi - user3578549
3个回答

6
我们还可以使用以下方法获取所有的交易并将其标记为已完成。
您可以在viewdidload方法中添加以下代码。
for transactionPending in SKPaymentQueue.default().transactions {
        SKPaymentQueue.default().finishTransaction(transactionPending)
    }

我尝试了许多其他的解决方案,但这个对我有效。现在,我可以多次购买产品。


这个解决方法可以帮助消除一些未完成的事务。但更好的方法是在应用程序启动时添加事务观察器,以便在所有情况下都完成这些事务(请参阅苹果公司的文档)。 - Josselin
谢谢。你救了我的一周。我不明白我的代码出了什么问题。一切都正常工作,突然间我就遇到了这个错误。使用了你的解决方案后,现在一切都正常工作了。 - Samrat Pramanik

6

我遇到了同样的问题。在这里修复了它:
我的IAP无法正常工作, Paymentqueue 函数存在错误。

以下是我找到的解决方案:

删除

SKPaymentQueue.defaultQueue().addTransactionObserver(self) 

将代码放在只执行一次的地方(仅限一个地方),比如说viewDidLoad()函数,并确保在每次应用程序启动时都能执行。

这样可以检查所有未完成的交易并在应用程序加载后结束它们,从而消除任何可能导致用户触发IAP的错误。

P.S .:此外,虽然这不是我的问题,但请确保为每个PurchaseState调用finishTransaction(),就像这里:

func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    print("Add Payment")

    for transaction:AnyObject in transactions{
        let trans = transaction as! SKPaymentTransaction
        print(trans.error)
        switch trans.transactionState{
        case .Purchased:
            print("IAP unlocked")
            print(p.productIdentifier)

            let prodID = p.productIdentifier as String
            switch prodID{
            case "IAP id":
                print("Keep on")
                keepOn()
            default:
                print("IAP not setup")
            }
            queue.finishTransaction(trans)
            break
        case .Failed:
            print ("Buy error")
            queue.finishTransaction(trans)
            break
        default:
            print("default: Error")
            break
        }
    }
}

永远不要忘记这一点:
queue.finishTransaction(trans)  

4
非常有帮助,谢谢!Ray Wenderlich关于IAP的教程中提出的方法存在问题,会导致某些交易在默认队列中“挂起”,从而出现“此应用内购买已被购买。它将免费恢复。”的警报,这对于可消耗的IAP尤其麻烦。 - cdf1982
2
同一个教程出现相同的问题。您修改后,如何完成待处理的交易并正常执行新代码? - GIJOW
2
完全不起作用。我只添加了一次观察者。收到消息后,它不会恢复交易并放弃它。 - TomSawyer
2
苹果的IAP文档建议在应用程序启动时将事务观察者添加到AppDelegate中。 - Josselin

0

我曾经遇到一个非续订订阅的相同问题。它显示已经被购买,可以免费恢复,但是却不能再购买其他订阅延期。

问题的一部分在于我的事务开关逻辑:

    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
            switch transaction.transactionState {
            case .purchased:
                complete(transaction: transaction)
            case .restored:
                restore(transaction: transaction)
                break
...

对于已购买的情况,我正在调用:

        SKPaymentQueue.default().finishTransaction(transaction)

但是在.restored情况下,我从未调用过finishTransaction。在开发过程中,我一定忘记了finishTransaction并且有一个“在队列中”,我从来没有完成。

我修复的方法是修改我的restoreTransaction,在确保订阅已记录在我的许可对象中后调用.finishTransaction。我检查了我没有重复订阅检查唯一的交易ID。

然后我尝试购买2次。第一次交易已完成,第二次我能够再次购买!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接