本文介绍了恢复购买:非消耗品的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我已经完成了一个小应用程序,我有一个非消耗品购买选项。它在App Store上。

I have completed a small app where I have a non-consumable purchase option. It is on the App Store.

购买该产品运行正常。这是我的恢复购买功能似乎什么都不做。

The purchase of the product runs OK. It's my Restore Purchase function that seems to do nothing.

我已为恢复购买添加了此代码 @IBAction

I have added this code for the Restore Purchase @IBAction:

@IBAction func restorePurchases(sender: AnyObject) {
    SKPaymentQueue.defaultQueue().addTransactionObserver(self)
    SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
}

但是没有任何反应我点击了恢复购买按钮。

But nothing happens when I hit the restore purchase button.

我想我必须添加一个功能来检查恢复是否成功。我打算将代码修改为以下内容:

I think I have to add a function that checks if the restore was successful or not. Am planning to amend code to the following:

@IBAction func restorePurchases(sender: AnyObject) {
    SKPaymentQueue.defaultQueue().addTransactionObserver(self)
    SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
}

func paymentQueue(queue: SKPaymentQueue!, updatedTransactions transactions: [AnyObject]!) {

for transaction:AnyObject in transactions {
    if let trans:SKPaymentTransaction = transaction as? SKPaymentTransaction{
        switch trans.transactionState {
        case .Restored:
            SKPaymentQueue.defaultQueue().finishTransaction(transaction as SKPaymentTransaction)
        var alert = UIAlertView(title: "Thank You", message: "Your purchase(s) were restored.", delegate: nil, cancelButtonTitle: "OK")
        alert.show()
            break;

        case .Failed:
            SKPaymentQueue.defaultQueue().finishTransaction(transaction as SKPaymentTransaction)
        var alert = UIAlertView(title: "Sorry", message: "Your purchase(s) could not be restored.", delegate: nil, cancelButtonTitle: "OK")
        alert.show()
        break;

        default:
        break;
        }
    }
}

这会诀窍吗?

我已经完成了与影响恢复购买交易有关的每个主题,我的研究让我了解了上述内容。所以我不认为这是一个问题的重复,但也许可以澄清如何成功恢复面临我类似情况的其他人的购买。

I have been through every thread in relation to effecting Restore Purchase transactions, and my research has led me to the above. So I don't think this is a duplicate of a question, but perhaps may clarify how to successfully restore purchases for others facing my similar situation.

推荐答案

你的代码在大多数情况下看起来都很好,尽管有些部分似乎来自较旧的教程。你应该做一些改变,其中一个就是你需要再次调用你的unlockProduct函数。

Your codes looks pretty fine for the most part, although some parts seem to be from older tutorials . There is some changes you should make, one of them is that you need to call your unlockProduct function again.

这是我使用的代码(Swift 3)。

This is the code I use (Swift 3).

/// Updated transactions
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {

    for transaction in transactions {
         switch transaction.transactionState {

        case .purchasing:
            // Transaction is being added to the server queue.

        case .purchased:
            // Transaction is in queue, user has been charged.  Client should complete the transaction.

            defer {
                queue.finishTransaction(transaction)
            }

            let productIdentifier = transaction.payment.productIdentifier

            unlockProduct(withIdentifier: productIdentifier)

        case .failed:
            // Transaction was cancelled or failed before being added to the server queue.

            defer {
                queue.finishTransaction(transaction)
            }

            let errorCode = (transaction.error as? SKError)?.code

            if errorCode == .paymentCancelled {
                print("Transaction failed - user cancelled payment")
            } else if errorCode == .paymentNotAllowed { // Will show alert automatically
               print("Transaction failed - payments are not allowed")
            } else {
                print("Transaction failed - other error")
                // Show alert with localised error description
            }

        case .restored:
            // Transaction was restored from user's purchase history.  Client should complete the transaction.

            defer {
                queue.finishTransaction(transaction)
            }

            if let productIdentifier = transaction.original?.payment.productIdentifier {
                unlockProduct(withIdentifier: productIdentifier)
            }

        case .deferred:
            // The transaction is in the queue, but its final status is pending external action
            // e.g family member approval (FamilySharing).
            // DO NOT freeze up app. Treate as if transaction has not started yet.
        }
    }
}

比使用委托方法显示恢复警报

Than use the delegate methods to show the restore alert

/// Restore finished
func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
    guard queue.transactions.count != 0 else {
        // showAlert that nothing restored
        return
    }

    // show restore successful alert
}

/// Restore failed
func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: NSError) {

     /// handle the restore error if you need to.
}

解锁产品只是一种方法我相信你已经拥有了。

Unlock product is just a method I am sure you already have too.

  func unlockProduct(withIdentifier productIdentifier: String) {
       switch productIdentifier {
         /// unlock product for correct ID
     }
  }

作为旁注,你应该移动这一行

As a side note, you should move this line

 SKPaymentQueue.default().add(self)

退出恢复和购买功能并将其放入viewDidLoad。

out of your restore and buy function and put it in viewDidLoad.

Apple建议您尽快添加事务观察器您的应用会启动,只有在您的应用关闭后才能将其删除遗憾的是,许多教程都没有正确地教你这个。这样您就不能确定任何不完整的交易,例如由于网络错误,将始终正确恢复。

Apple recommends you add the transaction observer as soon as your app launches and only remove it when your app is closed. A lot of tutorials unfortunately dont teach you this correctly. This way you unsure that any incomplete transactions e.g due to network error, will always resume correctly.

在我的实际项目中,我的IAP代码是在Singleton类中,所以我实际上使用委托将unlockProduct方法转发到处理gameData的类。我还可以确保在应用启动时添加观察者。

In my real projects my code for IAPs is in a Singleton class so I would actually using delegation to forward the unlockProduct method to my class that handles gameData. I can than also make sure the observer is added at app launch.

希望这有帮助

这篇关于恢复购买:非消耗品的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 16:40