Il mio IAP non funziona. Bug a func Paymentqueue

Quando faccio clic su uno dei miei IAPS, viene visualizzato un messaggio che indica che lo IAP è già stato acquistato (che non è il caso) e verrà ripristinato gratuitamente, quindi non accade nulla, l’IAP non viene eseguito.

Ecco cosa ricevo nella mia console:

No Value. IAP is enabled, loading... true Product Request Product Added IAP id Remove Ads Removes ads from the app. 2 Buy: IAP id Add Payment nil default: Error 

Ecco il mio codice:

GameViewController.Swift

 import UIKit import StoreKit class GameViewController: UIViewController, ADBannerViewDelegate, SKProductsRequestDelegate, SKPaymentTransactionObserver, GKGameCenterControllerDelegate,GADBannerViewDelegate{ @IBOutlet var outRemoveAds: UIButton! @IBOutlet var outRestorePurchases: UIButton! override func viewDidLoad() { super.viewDidLoad() } override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) if NSUserDefaults.standardUserDefaults().objectForKey("val") != nil { print("Has a value.") banner.removeFromSuperview() bannerGoogle.removeFromSuperview() outRemoveAds.removeFromSuperview() outRestorePurchases.removeFromSuperview() removeInterFrom = 1 } else { print("No Value.") } if(SKPaymentQueue.canMakePayments()){ print("IAP is enabled, loading...") let productID:NSSet = NSSet(objects:"IAP id") let request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set) request.delegate = self request.start() } else{ print("Please enable IAPS") } } //IAP Ads @IBAction func removeAds(sender: UIButton) { for product in list{ let prodID = product.productIdentifier if (prodID == "IAP id"){ p = product buyProduct() break } } } @IBAction func restorePurchases(sender: UIButton) { SKPaymentQueue.defaultQueue().addTransactionObserver(self) SKPaymentQueue.defaultQueue().restoreCompletedTransactions() } //IAP Functions var list = [SKProduct]() var p = SKProduct() func removeAds(){ banner.removeFromSuperview() bannerGoogle.removeFromSuperview() outRemoveAds.removeFromSuperview() outRestorePurchases.removeFromSuperview() let theValue = 10 NSUserDefaults.standardUserDefaults().setObject(theValue, forKey: "val") NSUserDefaults.standardUserDefaults().synchronize() } func buyProduct(){ print("Buy: "+p.productIdentifier) let pay = SKPayment (product: p) SKPaymentQueue.defaultQueue().addTransactionObserver(self) SKPaymentQueue.defaultQueue().addPayment(pay as SKPayment) } func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) { print("Product Request") let myProduct = response.products for product in myProduct{ print("Product Added") print(product.productIdentifier) print(product.localizedTitle) print(product.localizedDescription) print(product.price) list.append(product as SKProduct) } } func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { print("Add Payment") for transaction:AnyObject in transactions{ let trans = transaction as! SKPaymentTransaction print(trans.error) switch trans.transactionState{ case .Purchased: print("IAP unlocked") print(p.productIdentifier) let prodID = p.productIdentifier as String switch prodID{ case "IAP id": print("Remove Ads") removeAds() default: print("IAP not setup") } queue.finishTransaction(trans) break case .Failed: print ("Buy error") queue.finishTransaction(trans) break default: print("default: Error") break } } } func paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue) { print("Purchases Restored") _ = [] for transaction in queue.transactions { let t: SKPaymentTransaction = transaction as SKPaymentTransaction let prodID = t.payment.productIdentifier as String switch prodID{ case "IAP id": print("Remove Ads") removeAds() default: print("IAP not setup") } } } func finishTransaction(trans:SKPaymentTransaction){ print("Finshed Transaction") } func paymentQueue(queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) { print("Remove Transaction") } } 

MenuViewController.swift

     import UIKit import StoreKit import Social class MenuViewController: UIViewController, SKProductsRequestDelegate,SKPaymentTransactionObserver { @IBOutlet var outRestart: UIButton! @IBOutlet var outBuy: UIButton! override func viewDidLoad() { super.viewDidLoad() } override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) if(SKPaymentQueue.canMakePayments()){ print("IAP is enabled, loading...") let productID:NSSet = NSSet(objects:"IAP id") let request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set) request.delegate = self request.start() } else{ print("Please enable IAPS") } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func buy(sender: UIButton) { for product in list{ let prodID = product.productIdentifier if (prodID == "IAP id"){ p = product buyProduct() break } } } //IAP Functions var list = [SKProduct]() var p = SKProduct() func keepOn(){ buyornot = 1 Back() } func buyProduct(){ print("Buy: "+p.productIdentifier) let pay = SKPayment (product: p) SKPaymentQueue.defaultQueue().addTransactionObserver(self) SKPaymentQueue.defaultQueue().addPayment(pay as SKPayment) } func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) { print("Product Request") let myProduct = response.products for product in myProduct{ print("Product Added") print(product.productIdentifier) print(product.localizedTitle) print(product.localizedDescription) print(product.price) list.append(product as SKProduct) } } func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { print("Add Payment") for transaction:AnyObject in transactions{ let trans = transaction as! SKPaymentTransaction print(trans.error) switch trans.transactionState{ case .Purchased: print("IAP unlocked") print(p.productIdentifier) let prodID = p.productIdentifier as String switch prodID{ case "IAP id": print("Keep on") keepOn() default: print("IAP not setup") } queue.finishTransaction(trans) break case .Failed: print ("Buy error") queue.finishTransaction(trans) break default: print("default: Error") break } } } func finishTransaction(trans:SKPaymentTransaction){ print("Finshed Transaction") } func paymentQueue(queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) { print("Remove Transaction") } 

    Ho trovato la soluzione!

    Elimina

     SKPaymentQueue.defaultQueue().addTransactionObserver(self) 

    ovunque tu l’abbia e lo metti una volta (SOLO UNA VOLTA) in un posto dove verrà eseguito ogni volta che la tua app si avvia (l’ho messo in viewDidLoad ()).

    Verificherà tutte le transazioni non completate e le interromperà una volta caricata l’app, eliminando quindi eventuali errori prima che gli utenti attivino un IAP.

    (Se questa risposta, o questa domanda ti ha aiutato, non dimenticare di upvote;))

    PS: Inoltre, questo non era il mio problema, ma assicurati di completare Transaction () per ogni PurchaseState come qui:

     func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { print("Add Payment") for transaction:AnyObject in transactions{ let trans = transaction as! SKPaymentTransaction print(trans.error) switch trans.transactionState{ case .Purchased: print("IAP unlocked") print(p.productIdentifier) let prodID = p.productIdentifier as String switch prodID{ case "IAP id": print("Keep on") keepOn() default: print("IAP not setup") } queue.finishTransaction(trans) break case .Failed: print ("Buy error") queue.finishTransaction(trans) break default: print("default: Error") break } } } 

    Non dimenticarlo mai:

      queue.finishTransaction(trans)