2016-03-14 140 views
0

我已經完成了一個小應用程序,我有一個非消耗購買選項。它在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; 
     } 
    } 
}  

這是否有訣竅?

我已經完成了與恢復購買交易有關的每個線索,而且我的研究使我得到了上述結論。所以我不認爲這是一個問題的重複,但也許可以澄清如何成功恢復面臨類似情況的其他人的採購。

回答

2

你的代碼看起來很不錯,儘管有些部分似乎來自於較老的教程。您應該進行一些更改,其中之一是您需要再次調用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

在我真正的項目,我對單邊行動計劃的代碼在,所以我會用實際代表團轉發unlockProduct方法來我的類來處理GAMEDATA一個Singleton類。我也可以確保觀察者在應用程序啓動時添加。

希望這會有所幫助

+0

已採納您的代碼。 100%完美:-) –

+0

我的快樂,快樂的編碼 – crashoverride777

+0

從Xcode 7.3和swift 2.2開始,這個代碼必須稍微改變,因爲錯誤現在在枚舉中處理。我稍後會更新我的答案。查看http://stackoverflow.com/questions/36156724/unresolved-identifier-skerrorpaymentcancelled – crashoverride777

相關問題