ViewController respondsToSelector:在购买消费品时发送给解除分配的实例的消息

时间:2016-05-07 14:04:28

标签: ios swift2 in-app-purchase

我在测试模式下购买产品时遇到了一些麻烦。我有2个viewcontrollers。 viewcontroller2是IAP类。购买硬币工作得很好,它的显示器在视图控制器1的标签中完美地购买了硬币。因此,当我切换到viewcontroller1(我使用硬币)并返回viewcontroller2并再次点击购买按钮购买硬币时,它会崩溃。

viewcontroller2:

import UIKit
import StoreKit

public var coins = NSUserDefaults.standardUserDefaults().integerForKey("coins")
public var ads = NSUserDefaults.standardUserDefaults().boolForKey("purchased")

class ViewController2: UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver{

@IBOutlet var lblAd: UILabel!
@IBOutlet var lblCoinAmount: UILabel!

@IBOutlet var outRemoveAds: UIButton!
@IBOutlet var outAddCoins: UIButton!



// 1
override func viewDidLoad() {
    super.viewDidLoad()

    SKPaymentQueue.defaultQueue().addTransactionObserver(self)




    outRemoveAds.enabled = false
    outAddCoins.enabled = false

    // Set IAPS
    if(SKPaymentQueue.canMakePayments()) {
        print("IAP is enabled, loading")
        let productID:NSSet = NSSet(objects: "productId1", "productId2")
        let request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set<String>)

        request.delegate = self
        request.start()
    } else {
        print("please enable IAPS")
    }

    lblCoinAmount.text = "\(coins)"

}



// 2
@IBAction func btnRemoveAds(sender: UIButton) {
    for product in list {
        let prodID = product.productIdentifier
        if(prodID == "productId1") {
            p = product
            buyProduct()
            break;
        }
    }

}

// 3
@IBAction func btnAddCoins(sender: UIButton) {
    for product in list {
        let prodID = product.productIdentifier
        if(prodID == "productId2") {
            p = product
            buyProduct()
            break;
        }
    }

}

// 4
func removeAds() {
    //lblAd.removeFromSuperview()
    let adsDefault = NSUserDefaults.standardUserDefaults()
    adsDefault.setBool(true , forKey: "purchased")
    adsDefault.synchronize()

}

// 5
func addCoins() {
    coins = coins + 50
    lblCoinAmount.text = "\(coins)"

    let CoinsDefault = NSUserDefaults.standardUserDefaults()
    CoinsDefault.setInteger(coins, forKey: "coins")

}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


@IBAction func RestorePurchases(sender: UIButton) {
    //SKPaymentQueue.defaultQueue().addTransactionObserver(self)
    SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
}


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



func buyProduct() {
    print("buy " + p.productIdentifier)
    let pay = SKPayment(product: p)
    //SKPaymentQueue.defaultQueue().addTransactionObserver(self)
    SKPaymentQueue.defaultQueue().addPayment(pay)
}

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

    outRemoveAds.enabled = true
    outAddCoins.enabled = true
}

func paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue) {
    print("transactions restored")

    for transaction in queue.transactions {
        let t: SKPaymentTransaction = transaction

        let prodID = t.payment.productIdentifier as String

        switch prodID {
        case "productId1":
            print("remove ads")
            removeAds()
        case "productId2":
            print("add coins to account")
            addCoins()
        default:
            print("IAP not setup")
        }

    }
}


func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    print("add paymnet")

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

        switch trans.transactionState {

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

            let prodID = p.productIdentifier as String


            switch prodID {
            case "productId1":
                print("remove ads")
                removeAds()
            case "productId2":
                print("add coins to account")
                addCoins()

            default:
                print("IAP not setup")
            }

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

        }
    }
}

func finishTransaction(trans:SKPaymentTransaction)
{
    print("finish trans")
    SKPaymentQueue.defaultQueue().finishTransaction(trans)
}
func paymentQueue(queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction])
{
    print("remove trans");
}




}

enter image description here enter image description here

3 个答案:

答案 0 :(得分:1)

在viewcontrollers

中的 deinit 功能中使用以下代码
SKPaymentQueue.defaultQueue().removeTransactionObserver

答案 1 :(得分:1)

你错过了这一行:

override func viewWillDisappear(animated: Bool) {
    SKPaymentQueue.defaultQueue().removeTransactionObserver(self)
}

答案 2 :(得分:0)

您可以使用Instruments调查该错误。 分析您的应用程序(Cmd⌘+ I),然后选择名为Zombies的模板。

尝试再次崩溃应用。您应该获得有关“Zombie”对象的更多信息,以及当时的堆栈状态。 如果您无法找到原因,可以在扩展详细信息窗格中打开仪器的屏幕截图 - 如果可能的话,我会尝试提供帮助:)