正在删除 'Old' 恢复购买交易
Deleting 'Old' Restore Purchase Transactions
我一直在尝试在一个项目中测试“恢复购买”功能,但我不断遇到此错误:
Ignoring restoreCompletedTransactionsWithApplicationUsername: because
already restoring transactions
我删除了一个沙盒测试员帐户,我认为有一个恢复购买的帐户仍然陷入付款循环。我知道我永远不应该删除沙盒测试帐户,但现在有点晚了。
我能做些什么来清除在这个永无止境的循环中捕获的还原事务吗?
编辑:
我修改后的代码:
序言:
class InAppPurchaseViewController: UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver {
let defaults = NSUserDefaults.standardUserDefaults()
var product_id: NSString?;
@IBOutlet weak var unlockAction: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
... }
购买:
@IBAction func unlockAction(发件人:AnyObject){
product_id = "xxxx.iap.removeads";
//Check if product is purchased
if (defaults.boolForKey("purchased")){
print("User already purchased this")
// Hide a view or show content depends on your requirement
}
else if (!defaults.boolForKey("Purchased")){
print("User has not yet purchased this")
}
print("About to fetch the products");
// We check that user can make payments.
if (SKPaymentQueue.canMakePayments())
{
let productID:NSSet = NSSet(object: self.product_id!);
let productsRequest:SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set<String>);
productsRequest.delegate = self;
productsRequest.start();
print("User can make purchases and will fetch products from Apple Store now");
}else{
print("User can't make purchases");
}
}
// Proceed to buy the product.
func buyProduct(product: SKProduct){
print("Sending the Payment Request to Apple");
let payment = SKPayment(product: product)
SKPaymentQueue.defaultQueue().addPayment(payment);
}
func productsRequest (request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) {
let count : Int = response.products.count
if (count>0) {
let validProduct: SKProduct = response.products[0] as SKProduct
if (validProduct.productIdentifier == self.product_id) {
print(validProduct.localizedTitle)
print(validProduct.localizedDescription)
print(validProduct.price)
buyProduct(validProduct);
} else {
print(validProduct.productIdentifier)
}
} else {
print("nothing")
}
}
func request(request: SKRequest, didFailWithError error: NSError) {
print("Error Fetching product information");
}
func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
print("Received Payment Transaction Response from Apple");
for transaction:AnyObject in transactions {
if let trans:SKPaymentTransaction = transaction as? SKPaymentTransaction {
switch trans.transactionState {
case .Purchased:
print("Product Purchased")
let alert = UIAlertController(title: "Thank You.", message: "Thank you for your purchase!", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction)
defaults.setBool(true , forKey: "purchased")
break;
case .Failed:
print("Purchased Failed");
SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction)
break;
case .Restored:
print("Already Purchased");
SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
break;
default:
break;
}
}
}
}
恢复:
@IBAction func restorePurchases(sender: AnyObject) {
product_id = "xxxx.iap.removeads";
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)
let 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)
let alert = UIAlertView(title: "Sorry", message: "Your purchase(s) could not be restored.", delegate: nil, cancelButtonTitle: "OK")
alert.show()
break;
default:
break;
}
}
}
}
}
只需创建一个新的测试用户,进行购买,然后测试恢复。 Apple 确实很难让测试用户进行应用内购买。根据我的经验,我总是创建新的测试用户,因为你不能删除他们的任何旧购买。因此,如果您想对首次购买进行两次测试,则需要两个测试用户。
但是至于你的问题,你应该只用这种方法检查一次交易:
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
for(SKPaymentTransaction *transaction in transactions){
switch(transaction.transactionState){
case SKPaymentTransactionStateRestored:
NSLog(@"Transaction state -> Restored");
//add the same code as you did from SKPaymentTransactionStatePurchased here
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
并确保你也有这个:
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
NSLog(@"received restored transactions: %lu", (unsigned long)queue.transactions.count);
for(SKPaymentTransaction *transaction in queue.transactions){
if(transaction.transactionState == SKPaymentTransactionStateRestored){
//called when the user successfully restores a purchase
NSLog(@"Transaction state -> Restored");
//if you have more than one in-app purchase product,
//you restore the correct product for the identifier.
//For example, you could use
//if(productID == kRemoveAdsProductIdentifier)
//to get the product identifier for the
//restored purchases, you can use
//
//NSString *productID = transaction.payment.productIdentifier;
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
}
}
你应该这样调用恢复购买:
- (IBAction) restore {
//this is called when the user restores purchases, you should hook this up to a button
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
希望对您有所帮助!
我一直在尝试在一个项目中测试“恢复购买”功能,但我不断遇到此错误:
Ignoring restoreCompletedTransactionsWithApplicationUsername: because already restoring transactions
我删除了一个沙盒测试员帐户,我认为有一个恢复购买的帐户仍然陷入付款循环。我知道我永远不应该删除沙盒测试帐户,但现在有点晚了。
我能做些什么来清除在这个永无止境的循环中捕获的还原事务吗?
编辑:
我修改后的代码:
序言:
class InAppPurchaseViewController: UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver {
let defaults = NSUserDefaults.standardUserDefaults()
var product_id: NSString?;
@IBOutlet weak var unlockAction: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
... }
购买:
@IBAction func unlockAction(发件人:AnyObject){
product_id = "xxxx.iap.removeads"; //Check if product is purchased if (defaults.boolForKey("purchased")){ print("User already purchased this") // Hide a view or show content depends on your requirement } else if (!defaults.boolForKey("Purchased")){ print("User has not yet purchased this") } print("About to fetch the products"); // We check that user can make payments. if (SKPaymentQueue.canMakePayments()) { let productID:NSSet = NSSet(object: self.product_id!); let productsRequest:SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set<String>); productsRequest.delegate = self; productsRequest.start(); print("User can make purchases and will fetch products from Apple Store now"); }else{ print("User can't make purchases"); }
}
// Proceed to buy the product. func buyProduct(product: SKProduct){ print("Sending the Payment Request to Apple"); let payment = SKPayment(product: product) SKPaymentQueue.defaultQueue().addPayment(payment); } func productsRequest (request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) { let count : Int = response.products.count if (count>0) { let validProduct: SKProduct = response.products[0] as SKProduct if (validProduct.productIdentifier == self.product_id) { print(validProduct.localizedTitle) print(validProduct.localizedDescription) print(validProduct.price) buyProduct(validProduct); } else { print(validProduct.productIdentifier) } } else { print("nothing") }
}
func request(request: SKRequest, didFailWithError error: NSError) { print("Error Fetching product information"); } func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { print("Received Payment Transaction Response from Apple"); for transaction:AnyObject in transactions { if let trans:SKPaymentTransaction = transaction as? SKPaymentTransaction { switch trans.transactionState { case .Purchased: print("Product Purchased") let alert = UIAlertController(title: "Thank You.", message: "Thank you for your purchase!", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil)) self.presentViewController(alert, animated: true, completion: nil) SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction) defaults.setBool(true , forKey: "purchased") break; case .Failed: print("Purchased Failed"); SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction) break; case .Restored: print("Already Purchased"); SKPaymentQueue.defaultQueue().restoreCompletedTransactions() break; default: break; } } }
}
恢复:
@IBAction func restorePurchases(sender: AnyObject) { product_id = "xxxx.iap.removeads"; 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) let 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) let alert = UIAlertView(title: "Sorry", message: "Your purchase(s) could not be restored.", delegate: nil, cancelButtonTitle: "OK") alert.show() break; default: break; } } } }
}
只需创建一个新的测试用户,进行购买,然后测试恢复。 Apple 确实很难让测试用户进行应用内购买。根据我的经验,我总是创建新的测试用户,因为你不能删除他们的任何旧购买。因此,如果您想对首次购买进行两次测试,则需要两个测试用户。
但是至于你的问题,你应该只用这种方法检查一次交易:
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
for(SKPaymentTransaction *transaction in transactions){
switch(transaction.transactionState){
case SKPaymentTransactionStateRestored:
NSLog(@"Transaction state -> Restored");
//add the same code as you did from SKPaymentTransactionStatePurchased here
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
并确保你也有这个:
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
NSLog(@"received restored transactions: %lu", (unsigned long)queue.transactions.count);
for(SKPaymentTransaction *transaction in queue.transactions){
if(transaction.transactionState == SKPaymentTransactionStateRestored){
//called when the user successfully restores a purchase
NSLog(@"Transaction state -> Restored");
//if you have more than one in-app purchase product,
//you restore the correct product for the identifier.
//For example, you could use
//if(productID == kRemoveAdsProductIdentifier)
//to get the product identifier for the
//restored purchases, you can use
//
//NSString *productID = transaction.payment.productIdentifier;
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
}
}
你应该这样调用恢复购买:
- (IBAction) restore {
//this is called when the user restores purchases, you should hook this up to a button
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
希望对您有所帮助!