为啥没有调用 paymentQueue(_:shouldAddStorePayment:_:) ?

Posted

技术标签:

【中文标题】为啥没有调用 paymentQueue(_:shouldAddStorePayment:_:) ?【英文标题】:Why is paymentQueue(_:shouldAddStorePayment:_:) not being called?为什么没有调用 paymentQueue(_:shouldAddStorePayment:_:) ? 【发布时间】:2018-08-31 09:45:45 【问题描述】:

为什么没有调用 paymentQueue(:shouldAddStorePayment::)?

我确信我已经完成了我需要做的一切。

我声明了我自己的支持 SKPaymentTransactionObserver 协议的类:

import UIKit
import StoreKit
import AudioToolbox.Audioservices

class UTIPaymentTransactionObserver: NSObject, SKPaymentTransactionObserver 

    func paymentQueue(_ queue: SKPaymentQueue, shouldAddStorePayment payment: SKPayment, for product: SKProduct) -> Bool 

        print("!!! shouldAddStorePayment")

        AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)

        return false

    

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

        print("!!! updatedTransactions")

        for transaction in transactions 
            print("!!! transaction=", transaction)
            switch transaction.transactionState 
            // Call the appropriate custom method for the transaction state.
            case SKPaymentTransactionState.purchasing:
                showTransactionAsInProgress(transaction, deferred: false)
            case SKPaymentTransactionState.deferred:
                showTransactionAsInProgress(transaction, deferred: true)
            case SKPaymentTransactionState.failed:
                failedTransaction(transaction)
            case SKPaymentTransactionState.purchased:
                completeTransaction(transaction)
            case SKPaymentTransactionState.restored:
                restoreTransaction(transaction)
            
        

    

    func showTransactionAsInProgress(_ transaction: SKPaymentTransaction, deferred: Bool) 

        print("!!! showTransactionAsInProgress")

    

    func failedTransaction(_ transaction: SKPaymentTransaction) 

        print("!!! failedTransaction")

        SKPaymentQueue.default().finishTransaction(transaction)

    

    func completeTransaction(_ transaction: SKPaymentTransaction) 

        print("!!! completeTransaction")

        SKPaymentQueue.default().finishTransaction(transaction)

    

    func restoreTransaction(_ transaction: SKPaymentTransaction) 

        print("!!! restoreTransaction")

    


我添加了在调用 paymentQueue(:shouldAddStorePayment::) 时振动设备的代码,以指示实际调用了该方法。

我在全局声明了一个观察者类的实例:

internal let paymentTransactionObserver = UTIPaymentTransactionObserver()

我确定我在 AppDelegate 中添加了观察者:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 
    // Override point for customization after application launch.

    SKPaymentQueue.default().add(paymentTransactionObserver)

    return true

paymentQueue(:shouldAddStorePayment::) 方法中的打印语句从不打印,设备从不振动。好像没有调用那个方法。

paymentQueue(_:updatedTransactions:) 方法被调用。该方法中的打印语句已执行。

在这段代码中,我为 paymentQueue(:shouldAddStorePayment::) 方法返回了 false,但这并没有什么不同。这个过程就像我返回了一个真实的一样。该产品之前已经购买过,因此它会通过并让用户/测试人员再次购买。

任何帮助将不胜感激。

这是视图控制器的代码扩展,它从 App Store 检索产品并呈现允许用户购买产品的用户界面:

我调用 validateProductIdentifiers() 开始向用户销售产品的过程。

// MARK: - SKProductsRequestDelegate

extension CloudViewController: SKProductsRequestDelegate 

    func validateProductIdentifiers() 

        let url = Bundle.main.url(forResource: "Purchase", withExtension: "plist")!

        let nsArrayProductIdentifiers: NSArray = NSArray(contentsOf: url)!

        let productIdentifiers = nsArrayProductIdentifiers as! [String]

        print(productIdentifiers)

        let setProductIdentifers: Set = Set(productIdentifiers)

        let productsRequest = SKProductsRequest(productIdentifiers: setProductIdentifers)

        self.productsRequest = productsRequest

        productsRequest.delegate = self

        productsRequest.start()

    

    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) 

        print("!!! didReceive")

        self.products = response.products

        let alertMessage = "Would you like to purchase?"

        let alert = UIAlertController(title: nil, message: alertMessage, preferredStyle: .actionSheet)

        let actionYes = UIAlertAction(title: "Yes", style: .default) 

            action in

            // Purchase

            let product: SKProduct = response.products.first!

            let payment: SKMutablePayment = SKMutablePayment(product: product)
            SKPaymentQueue.default().add(payment)

        

        let actionNo = UIAlertAction(title: "No", style: .cancel, handler: nil)

        alert.addAction(actionYes)
        alert.addAction(actionNo)

        alert.popoverPresentationController?.barButtonItem = barButtonItemEnableDropbox

        present(alert, animated: true, completion: nil)

    


【问题讨论】:

您是如何开始购买的?此方法仅在用户在 App Store 中发起购买时调用,而不是在您在应用中发起购买时调用 @Paulw11 我在帖子底部添加了您的问题的答案以及我的代码。 对,所以你在你的应用程序中发起购买,所以这个委托方法不会按照它的文档被调用。此方法仅在用户从其设备上的 App Store 应用发起应用内购买时调用 @Paulw11 我确信文档意味着当用户购买时调用该方法,因为我的代码允许用户这样做。即使用户从我的应用程序进行购买,购买仍然来自 App Store。我误解了文档吗?你确定你是对的吗?这是我从以下渠道获取信息的地方:developer.apple.com/library/archive/documentation/… 不,如果在您的应用程序中启动购买,则无需调用此委托方法,因为您根本无法显示相关的用户界面。如果用户从 App Store 应用程序购买或在 App Store 应用程序中兑换代码以进行应用内购买,则调用此方法。例如,您的服务器可能无法验证购买收据,因此您可以返回 false 以推迟购买 【参考方案1】:

根据documentation 这个方法

当用户在 App Store 中开始应用内购买时会调用此委托方法,并且交易会在您的应用中继续进行。具体来说,如果您的应用已安装,则调用该方法。

当用户在 App Store 应用中兑换应用内购买的促销代码或在 App Store 应用中购买推广的应用内购买时,就会发生这种情况。

在您的应用中发起购买时不会调用它,因为您已经可以控制当用户在您的应用中时是否应允许购买。

【讨论】:

以上是关于为啥没有调用 paymentQueue(_:shouldAddStorePayment:_:) ?的主要内容,如果未能解决你的问题,请参考以下文章

我的IAP没有用。在func Paymentqueue的错误

我的 IAP 无法正常工作。 func Paymentqueue 中的错误

为啥当我使用 [:] 时我的子类的 __getitem__ 和 __setitem__ 没有被调用?

为啥元类的 __call__ 方法在类上调用,而原生类的 __call__ 没有?

为啥不调用draw(_ layer: CALayer, in ctx: CGContext) 没有空draw(_ rect: CGRect)?

为啥`type.__new__`调用`__init_subclass__`?