rocket101
rocket101

Reputation: 7537

Does not conform to protocol SKPaymentTransactionObserver

I am trying to implement in app purchases in a Swift app, of a consumable in-app purchase, with product ID productID

Research

Using this answer, I learned about the basic pattern for in app purchases, and tried to adapt it, like so. I do not need to use the NSUserDefaults method of having the app remember if a purchase is made, as I am handling that with a different solution.

Code

class ViewController: UICollectionViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver {
     viewDidLoad() {
         //Unimportant stuff left out
             product_id = "productID"
            SKPaymentQueue.defaultQueue().addTransactionObserver(self)
         }

        @IBAction func thisISTheButtonToTriggerTheInAppPurchases(sender: AnyObject) {

            if (SKPaymentQueue.canMakePayments()) {
            var productID:NSSet = NSSet(object: self.product_id!);
            var productsRequest:SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set<String>);
            productsRequest.delegate = self;
            productsRequest.start();
            print("Fetching Products");
        }else{
            print("can't make purchases");
        }

        }
     func buyProduct(product: SKProduct){
        print("Sending the Payment Request to Apple");
        var payment = SKPayment(product: product)
        SKPaymentQueue.defaultQueue().addPayment(payment);

    }

    func productsRequest (request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) {

        var count : Int = response.products.count
        if (count>0) {
            var validProducts = response.products
            var 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: [AnyObject]!)    {
        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");
                SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction)
                break;
            case .Failed:
                print("Purchased Failed");
                SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction)
                break;



            case .Restored:
                print("Already Purchased");
                SKPaymentQueue.defaultQueue().restoreCompletedTransactions() 


            default:
                break;
            }
        }
    }

}
}

Error

Type 'ViewController' does not conform to protocol 'SKPaymentTransactionObserver'

I researched this error a bit, and sources like this suggest that such an error is due to not having required functions.

According to Apple, paymentQueue:updatedTransactions: is the only one required, but I seem to be implementing that. A possible theory of mine is that I am not implementing it correctly - if true, how do I fix that?

Expected Behavior

The app presents, and if given favorable user input, performs the IAP with the ID productID.

Thanks for helping, and let me know if you need any more information!

Upvotes: 1

Views: 2954

Answers (1)

matt
matt

Reputation: 536028

It's very simple. The error is about SKPaymentTransactionObserver. Its only required method is:

func paymentQueue(queue: SKPaymentQueue,
    updatedTransactions transactions: [SKPaymentTransaction])

The signature for your method doesn't match that:

func paymentQueue(queue: SKPaymentQueue!, 
    updatedTransactions transactions: [AnyObject]!)

...so it isn't the same method, so you don't conform.

Upvotes: 6

Related Questions