我用一个班来购买&下载书籍。 在viewWillAppear中,我请求产品的本地化价格在UILabel中显示:
class Books: UIViewController, ... {
override func viewWillAppear(animated: Bool) {
requestProductInfo()
}
func requestProductInfo() {
if SKPaymentQueue.canMakePayments() {
var productIdentifiers: NSSet = NSSet(object: "com.jauzee.myProduct")
var productRequest = SKProductsRequest(productIdentifiers: productIdentifiers as Set<NSObject>)
productRequest.delegate = self
productRequest.start()
}
}
}
问题是:如果我关闭Books VC并且requestProductInfo()正在进行应用程序崩溃(有错误,我无法读取)。
如何在申请产品信息时关闭图书VC安全?
我一直在尝试为请求产品信息制作特殊帮助类:
import Foundation
import StoreKit
class InAppHelper: NSObject, SKProductsRequestDelegate {
func requestProductPrice() {
if SKPaymentQueue.canMakePayments() {
var productIdentifiers: NSSet = NSSet(object: "com.jauzee.myProduct")
var productRequest = SKProductsRequest(productIdentifiers: productIdentifiers as Set<NSObject>)
productRequest.delegate = self
productRequest.start()
}
}
func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) {
var products: NSArray = response.products
var count : Int = response.products.count
if count > 0 {
var product: SKProduct = products[0] as! SKProduct
userDefaults.setObject(product.localizedPrice(), forKey: "localizedPrice");
}
}
}
但是当我从Books VC中调用requestProductPrice()时:
class Books: UIViewController, ... {
override func viewWillAppear(animated: Bool) {
...
var inAppHelper = InAppHelper()
inAppHelper.requestProductPrice()
...
}
}
它不会调用 didReceieveResponse 委托方法。
如何正确地请求应用内购买产品信息?或者如何让课程来请求该信息?
更新 我试着:
deinit {
SKPaymentQueue.defaultQueue().removeTransactionObserver(self)
productRequest?.delegate = nil
productRequest?.cancel()
}
在Books VC中,但它没有帮助。这是否意味着问题出在其他地方(不是在dealloc VC中,而是在其他地方......)?或者我不这样做(deinit)?
答案 0 :(得分:2)
在第一个示例中,当您远离它时,您的Books视图控制器将被释放。您尚未停止产品请求,更重要的是,我们未设置您分配给产品请求的代理。请求完成后,它会尝试调用您现在取消分配的Books视图控制器。这就是应用程序崩溃的原因。
要解决此问题,您需要保留对请求的引用,以便在Books视图控制器消失之前将委托设置为nil。
我过去在这种情况下通常做的是在应用程序的生命周期早期分配一个帮助程序实例。帮助程序请求所有IAP产品的启动时间。由于它从未被解除分配,因此它充当请求代理。您可以通过只读属性将产品提供给Books视图控制器。由于它从未被解除分配,因此您不会遇到第一个示例中出现的崩溃问题。长期帮助程序实例的另一个优点是,在视图控制器想要显示它时,您通常会拥有所有产品信息。在显示IAP列表(您已经拥有它们)时不会有延迟,并且您不需要在视图控制器上实现-didReceiveResponse
代理(因为您正在尝试在你的第二个例子中做。)