【问题标题】:How to centralizing IAP in main.swift如何在 main.swift 中集中 IAP
【发布时间】:2014-11-07 18:54:09
【问题描述】:

我正在尝试将我所有的 IAP 代码放在一个名为 iapController 的类中,并将其放在 main.swift 中。代码如下:

class iapController: UIViewController, SKPaymentTransactionObserver, SKProductsRequestDelegate {

var product:SKProduct!

class func offerUnlockLevels() {
    SKPaymentQueue.defaultQueue().addTransactionObserver(self)
    getProductInfo()
    let payment:SKPayment = SKPayment (product: product)
    SKPaymentQueue.defaultQueue().addPayment(payment)
}

func paymentQueue(queue: SKPaymentQueue!, updatedTransactions transactions: [AnyObject]!) {
    for transaction:AnyObject in transactions {
        if let trans:SKPaymentTransaction = transaction as? SKPaymentTransaction {
            switch trans.transactionState {
            case .Purchased:
                println("inside purchased")
                self.openAllLevels()
                SKPaymentQueue.defaultQueue().finishTransaction(transaction as SKPaymentTransaction)
                break
            case .Failed:
                println("inside failed")
                SKPaymentQueue.defaultQueue().finishTransaction(transaction as SKPaymentTransaction)
                break
            case .Restored:
                println("inside restored")
                SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
                break
            default:
                break
            }
        }
    }
}


func openAllLevels() {
    println("inside openAllLevels()")
    unlockAllLevelsButton.hidden = true
    for var i=0; i<20; i++ {
        levelCollectionButtons[i].setBackgroundImage(nil, forState: .Normal)
    }
}

func productsRequest (request: SKProductsRequest!, didReceiveResponse response: SKProductsResponse!) {
    let products = response.products
    println(products)
    if products.count != 0
    {
        product = products[0] as SKProduct
        println(product.localizedTitle + "\n" + product.localizedDescription)
    }
}

func getProductInfo() { //Checks if user can make IAP (has itunes account)
    if (SKPaymentQueue.canMakePayments()) {
        let productID:NSSet = NSSet(object: "Zero.UnlockAllLevels") //Hold our product ID
        let request:SKProductsRequest = SKProductsRequest(productIdentifiers: productID)
        request.delegate = self
        request.start()
    }
}

}

请注意,我将 offerUnlockLevels() 设为类级别函数,因为我想从其他视图控制器调用它。但是我收到错误:类型 iapController.Type 不符合协议 'SKPaymentTransactionObserver'

如果我不将其设为类级函数,我将无法从其他视图控制器类中调用此函数。我做错了什么?

【问题讨论】:

    标签: ios xcode swift xcode6


    【解决方案1】:

    如果我不将其设为类级函数,我将无法从其他视图控制器类中调用此函数

    当然可以。您可以从其他视图控制器调用视图控制器实例方法。您可以在 any 类的实例上调用 any 实例方法,只要它不是私有的。这就是 for 的实例方法。

    例如,当你说

    self.navigationController!.pushViewController(someVC, animated:true)
    

    ...您正在调用视图控制器的实例方法 - 导航控制器是视图控制器,pushViewController:animated: 是实例方法,而不是类方法。

    所以,去掉class 的名称,让offerUnlockLevels 成为一个实例方法,你就可以在iapController 类的任何实例上调用它。

    【讨论】:

    • 但是,我还不清楚为什么您希望它成为 UIViewController 子类。你为什么不把它变成一个 NSObject 子类呢?它显然没有控制任何视图;它只是与 StoreKit 相关的功能包。您似乎不太了解什么是类和实例。如果是这样的话,我建议你停下来了解一下,因为否则你无法进行面向对象的编程。
    • 从其他 viewcontroller 类 (LevelsViewController) 我调用了 self.iapController!.offerUnlockLevels() 但它给出错误 'LevelsViewController' 没有名为 iapController 的成员。
    • 嗯,那是因为它没有。要调用实例方法,您需要创建(准备好)一个实例。你需要创建一个 iapController 的实例,然后,如果你想使用你正在使用的调用语法,你还需要将它分配给 LevelsViewController 的iapController 属性。
    • 但是,我不明白您为什么不将所有与 SK 相关的功能都放在应用程序委托中。那是通常的地方。它有一个明显的优势,那就是这是一个永远存在的实例。或者,如果 LevelsViewController 将一直存在,那么只需将与 SK 相关的功能放在那里,而不是在故事中引入额外的对象/类。
    • 谢谢,实例解决了问题。我是新手,因此有点麻烦 :) 感谢您的耐心等待。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多