删除“旧”还原购买交易

时间:2016-03-16 15:45:48

标签: ios swift in-app-purchase

我一直在尝试在项目中测试“恢复购买”功能,但我面临着这个错误的持续反馈:

  

忽略restoreCompletedTransactionsWithApplicationUsername:因为   已经恢复交易

我删除了一个沙盒测试程序帐户,我认为还有一个恢复购买仍然在付款循环中。我意识到我永远不应该删除一个沙箱测试帐户,但这有点晚了。

我能做些什么来清除这个永无止境的循环中捕获的恢复交易吗?

编辑:

我修改过的代码:

前同步码:

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()
}
... }
  1. 购买:

    @IBAction func unlockAction(sender: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;
            }
        }
    }
    

    }

  2. 恢复:

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

    }

1 个答案:

答案 0 :(得分:2)

只需创建一个新的测试用户,进行购买,然后测试还原。 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];

}

希望有所帮助!