Swift, spritekit: In app purchase code runs, NOTHING happens?

微笑、不失礼 提交于 2019-12-12 12:49:29

问题


Ok, so I'm working in Swift and I just need help. I have followed 4 different tutorials on how to implement in app purchases in sprite kit with Swift, copied code verbatim, and nothing is working for me.

Here are the steps I have taken:

  1. Gone in Itunes Connect and created an in app purchase under my app's record. My in app purchase's product Id is "GameOverSaveSavior"

  2. In Xcode, I've turned my app's In app purchase capability to ON, made sure my team is set to my account, and made sure my Bundle Identifier under info is set to my app's bundle identifier in ITunes Connect

  3. Before writing any code, I have import StoreKit in my GameScene.swift file

As for code, this is what I have done:

(1) In Gamescene.swift, at the end of my didMoveToView func, I have:

// Set IAPS
        if(SKPaymentQueue.canMakePayments()) {
            println("IAP is enabled, loading")
            var productID:NSSet = NSSet(objects: "GameOverSaveSavior")
            var request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as Set<NSObject>)
            request.delegate = self
            request.start()
        } else {
            println("please enable IAPS")
        }

This outputs "IAP is enabled, loading" when the app is run.

(2) In GameScene.swift, within the class but outside of didMoveToView, I have all the functions and variables others have used for in app purchases:

var list = [SKProduct]()
var p = SKProduct()

    func purchaseMade() {
        println("they bought it!")
    }

    func buyProduct() {
        println("buy" + p.productIdentifier)

        var pay = SKPayment(product: p)
        SKPaymentQueue.defaultQueue().addTransactionObserver(self)
        SKPaymentQueue.defaultQueue().addPayment(pay as SKPayment)
    }
    func productsRequest(request: SKProductsRequest!, didReceiveResponse response: SKProductsResponse!) {
        println("product request")
        var myProduct = response.products

        for product in myProduct {
            println("product added")
            println(product.productIdentifier)
            println(product.localizedTitle)
            println(product.localizedDescription)
            println(product.price)

            list.append(product as! SKProduct)
        }
    }

    func paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue!) {
        println("transactions restored")

        var purchasedItemIDS = []
        for transaction in queue.transactions {
            var t: SKPaymentTransaction = transaction as! SKPaymentTransaction

            let prodID = t.payment.productIdentifier as String

            switch prodID {
            case "GameOverSaveSavior":

                purchaseMade()

                //Right here is where you should put the function that you want to execute when your in app purchase is complete
            default:
                println("IAP not setup")
            }

        }

        var alert = UIAlertView(title: "Thank You", message: "Your purchase(s) were restored. You may have to restart the app before banner ads are removed.", delegate: nil, cancelButtonTitle: "OK")
        alert.show()
    }


    func paymentQueue(queue: SKPaymentQueue!, updatedTransactions transactions: [AnyObject]!) {
        println("add paymnet")

        for transaction:AnyObject in transactions {
            var trans = transaction as! SKPaymentTransaction
            println(trans.error)

            switch trans.transactionState {

            case .Purchased, .Restored:
                println("buy, ok unlock iap here")
                println(p.productIdentifier)

                let prodID = p.productIdentifier as String
                switch prodID {
                case "GameOverSaveSavior":

                    //Here you should put the function you want to execute when the purchase is complete
                    var alert = UIAlertView(title: "Thank You", message: "You may have to restart the app before the banner ads are removed.", delegate: nil, cancelButtonTitle: "OK")
                    alert.show()
                default:
                    println("IAP not setup")
                }

                queue.finishTransaction(trans)
                break;
            case .Failed:
                println("buy error")
                queue.finishTransaction(trans)
                break;
            default:
                println("default")
                break;

            }
        }
    }

    func finishTransaction(trans:SKPaymentTransaction)
    {
        println("finish trans")
    }
    func paymentQueue(queue: SKPaymentQueue!, removedTransactions transactions: [AnyObject]!)
    {
        println("remove trans");
    }

This outputs "product request" to the console when the app is run.

(3) In GameScene.swift, in my touchesBegan func, I have the following for when the right button is touched:

//In app purchase
            if touchedNode == saveMeBtn {

                println("button touched!")
                for product in list {
                    var prodID = product.productIdentifier
                    if(prodID == "GameOverSaveSavior") {
                        p = product
                        buyProduct()  //This is one of the functions we added earlier
                        break;
                    }
                }

This outputs "button touched!" when the button is touched.

I do not know what I am doing wrong. The code compiles with no errors, yet nothing occurs when my button is touched. There is no alert asking the user to sign in or to purchase anything- nothing. I have mainly followed this question: in app purchase in SKScene

Is there anything else I should have done prior to writing the code? Am I missing something in my code?


回答1:


I think I can help you:

I had your issue in the past. And another similar one which I fixed here: My IAP isn't working. Bugs at func Paymentqueue

Here is the solution I had found:

Delete

SKPaymentQueue.defaultQueue().addTransactionObserver(self) 

everywhere you have it and put it once (ONLY ONCE) in a place where it will be executed each time your app boots up ( I put it in viewDidLoad()).

This will check for all unfinished transactions and terminate them once the app has loaded, thus removing any possible errors before your users triggers an IAP.

(If this answer helped you, don't forget to upvote ;))

P.S.: Also, this wasn't my issue, but make sure to finishTransaction() for each PurchaseState, like here:

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

Never forget this:

 queue.finishTransaction(trans)

And make separate case for .Restored.



来源:https://stackoverflow.com/questions/32419049/swift-spritekit-in-app-purchase-code-runs-nothing-happens

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!