簡體   English   中英

恢復購買:非消耗品

[英]Restore Purchase : Non-Consumable

我已經完成了一個小應用程序,其中有一個非消耗品購買選項。 它在 App Store 上。

產品的購買運行正常。 這是我的恢復購買功能,似乎什么都不做。

我已經為恢復購買@IBAction添加了這段代碼:

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

但是當我點擊恢復購買按鈕時沒有任何反應。

我想我必須添加一個檢查恢復是否成功的函數。 我計划將代碼修改為以下內容:

@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;
        }
    }
}    

這會奏效嗎?

我經歷了與影響恢復購買交易有關的每一個線索,我的研究使我達到了上述目的。 所以我不認為這是一個問題的重復,但也許可以澄清如何為面臨我類似情況的其他人成功恢復購買。

您的代碼在大多數情況下看起來都不錯,盡管某些部分似乎來自較舊的教程。 您應該進行一些更改,其中之一是您需要再次調用unlockProduct函數。

這是我使用的代碼(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.
        }
    }
}

比使用委托方法顯示還原警報

/// 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. 
}

解鎖產品只是我確定您已經擁有的一種方法。

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

作為旁注,您應該移動此行

 SKPaymentQueue.default().add(self)

退出您的還原和購買功能,並將其放入viewDidLoad中。

Apple建議您在應用程序啟動后立即添加事務觀察器,並僅在應用程序關閉時將其刪除。 不幸的是,很多教程都沒有正確地教您這一點。 這樣,您就可以確保任何未完成的事務(例如由於網絡錯誤)始終可以正確恢復。

https://developer.apple.com/library/content/technotes/tn2387/_index.html

在我的真實項目中,IAP的代碼在Singleton類中,因此我實際上將使用委托將unlockProduct方法轉發給處理gameData的類。 然后,我還可以確保在應用啟動時添加了觀察者。

希望這可以幫助

我花了一些時間才弄清楚,但我的 StoreKit 沒有更新交易和恢復購買的原因是因為我的應用程序方案中的配置設置損壞。 當我將其設置為無時,它起作用了!

在 Xcode 中,我進入 Edit>Scheme (image1) 單擊 Run>Options 選項卡並為 StoreKit Configuration (image2) 選擇 None。 我還使用了我的物理設備,並退出了我的個人 Apple 購買帳戶(設置 > 頂部的您的姓名/圖片 > 媒體和購買 > 退出)(圖 3)。 最后,這一步可能並不重要,但我在設備上的“設置”>“應用商店”菜單(圖像 4 和圖像 5)底部登錄了我的測試沙盒帳戶。 這是我在 developer.apple.com 中在測試用戶下設置的帳戶。

編輯方案 運行選項 購買關閉 應用商店設置 測試用戶沙箱登錄

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM