用户为什么没有在Swift iOS中获得应用内购买确认?

时间:2019-09-03 00:38:29

标签: ios swift in-app-purchase

我在警报视图中显示IAP选项,这是我用来执行此操作的代码:

paidAlert.addAction(UIAlertAction(title: "Purchase", style: UIAlertAction.Style.default, handler: { (action) in
                IAPHandler.shared.purchaseMyProduct(index: 0)

            }))
            paidAlert.addAction(UIAlertAction(title: "Restore", style: UIAlertAction.Style.default, handler: { (action) in
                IAPHandler.shared.restorePurchase()

            }))
            paidAlert.addAction(UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler: { (action) in

            }))

我在另一个Swift文件中处理实际的IAP,该文件发布在这里:

    import UIKit
import StoreKit

enum IAPHandlerAlertType{
    case disabled
    case restored
    case purchased

    func message() -> String{
        switch self {
        case .disabled:

            let notificationFeedbackGenerator = UINotificationFeedbackGenerator()
            notificationFeedbackGenerator.prepare()
            notificationFeedbackGenerator.notificationOccurred(.error)

            return "Purchases are disabled on your device."
        case .restored:

            let notificationFeedbackGenerator = UINotificationFeedbackGenerator()
            notificationFeedbackGenerator.prepare()
            notificationFeedbackGenerator.notificationOccurred(.success)

            return "Unlimited strategies have been successfully unlocked. You can restore this purchase using this Apple ID on other devices."
        case .purchased:

            let notificationFeedbackGenerator = UINotificationFeedbackGenerator()
            notificationFeedbackGenerator.prepare()
            notificationFeedbackGenerator.notificationOccurred(.success)

            return "Unlimited strategies have been successfully unlocked. You can restore this purchase using this Apple ID on other devices."
        }
    }
}

class IAPHandler: NSObject {
    static let shared = IAPHandler()

    let NON_CONSUMABLE_PURCHASE_PRODUCT_ID = "com.isaranjha.opc.fullversion"

    fileprivate var productID = ""
    fileprivate var productsRequest = SKProductsRequest()
    fileprivate var iapProducts = [SKProduct]()

    var purchaseStatusBlock: ((IAPHandlerAlertType) -> Void)?

    // MARK: - MAKE PURCHASE OF A PRODUCT
    func canMakePurchases() -> Bool {  return SKPaymentQueue.canMakePayments()  }

    func purchaseMyProduct(index: Int){
        if iapProducts.count == 0 { return }

        if self.canMakePurchases() {
            let product = iapProducts[index]
            let payment = SKPayment(product: product)
            SKPaymentQueue.default().add(self)
            SKPaymentQueue.default().add(payment)

            print("PRODUCT TO PURCHASE: \(product.productIdentifier)")
            productID = product.productIdentifier
        } else {
            purchaseStatusBlock?(.disabled)
        }
    }

    // MARK: - RESTORE PURCHASE
    func restorePurchase(){
        SKPaymentQueue.default().add(self)
        SKPaymentQueue.default().restoreCompletedTransactions()
    }

    // MARK: - FETCH AVAILABLE IAP PRODUCTS
    func fetchAvailableProducts(){

        // Put here your IAP Products ID's
        let productIdentifiers = NSSet(objects: NON_CONSUMABLE_PURCHASE_PRODUCT_ID
        )

        productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers as! Set<String>)
        productsRequest.delegate = self
        productsRequest.start()
    }
}

extension IAPHandler: SKProductsRequestDelegate, SKPaymentTransactionObserver{
    // MARK: - REQUEST IAP PRODUCTS
    func productsRequest (_ request:SKProductsRequest, didReceive response:SKProductsResponse) {

        if (response.products.count > 0) {
            iapProducts = response.products
            for product in iapProducts{
                let numberFormatter = NumberFormatter()
                numberFormatter.formatterBehavior = .behavior10_4
                numberFormatter.numberStyle = .currency
                numberFormatter.locale = product.priceLocale
                let price1Str = numberFormatter.string(from: product.price)
                print(product.localizedDescription + "\nfor just \(price1Str!)")
            }
        }
    }

    func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
        purchaseStatusBlock?(.restored)
    }

    // MARK:- IAP PAYMENT QUEUE
    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction:AnyObject in transactions {
            if let trans = transaction as? SKPaymentTransaction {
                switch trans.transactionState {
                case .purchased:
                    print("purchased")
                    SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
                    purchaseStatusBlock?(.purchased)
                    break

                case .failed:
                    print("failed")
                    SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
                    break
                case .restored:
                    print("restored")
                    SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
                    break

                default: break
                }}}
    }
}

但是,多个用户(但不是所有用户)报告说他们能够购买IAP罚款(向他们收取费用和所有费用),但他们没有得到我所输入的任何确认信息(警告说购买成功等),因此未购买任何功能。我们唯一能找到的解决方法是用户需要从多任务处理中终止该应用程序,再次获得初始IAP购买警报,但选择“还原”,然后相应地提示并解锁功能。

我无法弄清楚问题出在哪里,但是看到“恢复”功能似乎如何工作,我假设我在实际购买中缺少一些东西,可以正确调用该案例并显示警报。

感谢您的帮助。

0 个答案:

没有答案