【问题标题】:In-App Purchase redirects to another view controller应用内购买重定向到另一个视图控制器
【发布时间】:2018-01-09 18:49:41
【问题描述】:

我已经玩了几天的应用内购买并发现了下一个问题(如果预期行为,请告诉我)。

我目前在 TestFlight 上有应用程序,而不是在 Apple Store。

我有一个用户可以购买的项目列表,当用户点击“购买”时,它会执行所有正常步骤:选择产品,然后我显示我的 AlertViewController 并确认购买,并在完成“提交”时AlertViewController 的操作我在我的 IAP Manager 中调用 buyProduct 。然后关于“取消/购买”的正常对话框出现在“确认您的应用内购买”对话框中,带有 [Environment: Sandbox] 等。

但是,当我点击“购买”时,我会被重定向到之前的视图控制器并且“一切就绪”。显示在上一个 View Controller 上,而不是我所在的那个。

如果 TestFlight 版本没问题 - 那么很好。如果这是我在 Apple Store 的行为,那么我需要修复它是很糟糕的。这是我的应用内购买经理:

class IAPManager: NSObject {
static let sharedInstance = IAPManager()

static let IAPManagerPurchaseNotification = "IAPManagerPurchaseNotification"

fileprivate var productsRequest: SKProductsRequest?
fileprivate var productsRequestCompletionHandler: ProductsRequestCompletionHandler?

func initialize() {
    SKPaymentQueue.default().add(self)
}

func deinitialize() {
    SKPaymentQueue.default().remove(self)
}

/// Request products from Apple Store.
/// - parameter products: IAPProduct to purchase.
func requestProduct(products: [IAPProduct], _ completionHandler: @escaping ProductsRequestCompletionHandler) {
    productsRequest?.cancel()
    productsRequestCompletionHandler = completionHandler

    var productIdentifiers: Set<String> = Set<String>()
    for product in products {
        productIdentifiers.insert(product.rawValue)
    }

    productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers)
    productsRequest?.delegate = self
    productsRequest?.start()
}

/// Does actual purchasing against Apple Store.
/// - parameter product: product that user wants to purchase.
func buyProduct(_ product: SKProduct) {
    Log.info(message: "User \(UsersManager.sharedInstance.currentUserId) is purchasing \(product.productIdentifier)", sender: self)
    let payment = SKPayment(product: product)
    SKPaymentQueue.default().add(payment)
}

class func canMakePayments() -> Bool {
    return SKPaymentQueue.canMakePayments()
}

/// Restores previously purchased non-consumable items.
func restorePurchases() {
    SKPaymentQueue.default().restoreCompletedTransactions()
}
}

extension IAPManager: SKProductsRequestDelegate {
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
    Log.info(message: "Loaded list of products...", sender: self)
    let products = response.products
    productsRequestCompletionHandler?(true, products)
    clearRequestAndHandler()

    for p in products {
        Log.info(message: "Found product: \(p.productIdentifier) \(p.localizedTitle) \(p.price.floatValue)", sender: self)
    }
}

func request(_ request: SKRequest, didFailWithError error: Error) {
    Log.error(message: "Failed to load list of products with error: \(error.localizedDescription)", sender: self)
    productsRequestCompletionHandler?(false, nil)
    clearRequestAndHandler()
}

private func clearRequestAndHandler() {
    productsRequest = nil
    productsRequestCompletionHandler = nil
}
}

extension IAPManager: SKPaymentTransactionObserver {
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    for transaction in transactions {
        switch (transaction.transactionState) {
            case .purchased: complete(transaction: transaction)
            case .failed: fail(transaction: transaction)
            case .restored: restore(transaction: transaction)
            case .deferred: Log.info(message: "Purchase is deffered", sender: self)
            case .purchasing: Log.info(message: "Purchase is in progress", sender: self)
        }
    }
}

private func complete(transaction: SKPaymentTransaction) {
    Log.info(message: "Purchase is completed.", sender: self)
    deliverPurchaseNotificationFor(identifier: transaction.payment.productIdentifier)
    SKPaymentQueue.default().finishTransaction(transaction)
}

private func restore(transaction: SKPaymentTransaction) {
    guard let productIdentifier = transaction.original?.payment.productIdentifier else {
        return
    }

    Log.info(message: "Purchase \(productIdentifier) is in restore state.", sender: self)
    deliverPurchaseNotificationFor(identifier: productIdentifier)

    SKPaymentQueue.default().finishTransaction(transaction)
}

private func fail(transaction: SKPaymentTransaction) {
    Log.info(message: "Purchase is failed.", sender: self)
    if let transactionError = transaction.error as NSError? {
        if transactionError.code != SKError.paymentCancelled.rawValue {
            Log.error(message: "Transaction Error: \(transactionError.localizedDescription)", sender: self)
        }
    }

    SKPaymentQueue.default().finishTransaction(transaction)
}

private func deliverPurchaseNotificationFor(identifier: String?) {
    guard let identifier = identifier else {
        return
    }

    NotificationCenter.default.post(name: NSNotification.Name(rawValue: IAPManager.IAPManagerPurchaseNotification), object: identifier)
}
}

调用 IAPManager 的代码:

let alert = UIAlertController(title: "<Title>", message: "<Message>", preferredStyle: .alert)
IAPManager.sharedInstance.requestProduct(products: [product]) { success, products in
        guard success, let products = products, !products.isEmpty else {
            Log.error(message: "Error occured during product request.", sender: self)
            return
        }

        let product = products[0]

        let submit = UIAlertAction(title: "Ok", style: .default) { action in                
            IAPManager.sharedInstance.buyProduct(product)
        }

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

        alert.addAction(submit)
        alert.addAction(cancel)

        self.present(alert, animated: true, completion: nil)
    }

【问题讨论】:

  • 这不是一种常见的行为@Array,检查你的警报功能是他们编写的任何可以让你返回的代码
  • 不,我更新了调用应用内购买管理器的代码
  • 顺便说一句,问题自行消失了。也许这是由其他因素造成的。

标签: ios swift in-app-purchase


【解决方案1】:

问题自行消失。我正在修复多线程,可能这就是原因。我现在无法重现,但如果我能找到真正的原因 - 我会在这里发布。谢谢大家。

【讨论】:

    猜你喜欢
    • 2014-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 2020-05-17
    相关资源
    最近更新 更多