我一直在跟踪this RW教程,并且与许多IAP和Storekit教程一样,它们都谈论用户首次购买IAP的流程,但是他们没有详细说明应用程序在何时运行的方式。已经购买了IAP的用户会再次打开该应用。

找到问题的关键时更新我的​​问题:

据我所知,阻止/显示内容的代码是对(1)收据和(2)SessionID的查找……他没有在本教程中详细讨论SessionID的用途或是否它只是该教程的演示的一部分。例如,只有在调用uploadReceipt时才设置(只有在调用handlePurchasedStatehandleRestoredState时才调用)。换句话说,如果用户打开已经有订阅的应用,则没有运行任何代码来设置SessionID,因此内容永远不会被解锁吗?

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

  var window: UIWindow?

  func application(_ application: UIApplication,
                   didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    SKPaymentQueue.default().add(self)
    SubscriptionService.shared.loadSubscriptionOptions()
    return true
  }
}


// MARK: - SKPaymentTransactionObserver

extension AppDelegate: SKPaymentTransactionObserver {

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

    for transaction in transactions {
      switch transaction.transactionState {
      case .purchasing:
        handlePurchasingState(for: transaction, in: queue)
      case .purchased:
        handlePurchasedState(for: transaction, in: queue)
      case .restored:
        handleRestoredState(for: transaction, in: queue)
      case .failed:
        handleFailedState(for: transaction, in: queue)
      case .deferred:
        handleDeferredState(for: transaction, in: queue)
      }
    }
  }

  func handlePurchasingState(for transaction: SKPaymentTransaction, in queue: SKPaymentQueue) {
    print("User is attempting to purchase product id: \(transaction.payment.productIdentifier)")
  }

  func handlePurchasedState(for transaction: SKPaymentTransaction, in queue: SKPaymentQueue) {
    print("User purchased product id: \(transaction.payment.productIdentifier)")

    queue.finishTransaction(transaction)
    SubscriptionService.shared.uploadReceipt { (success) in
      DispatchQueue.main.async {
        NotificationCenter.default.post(name: SubscriptionService.purchaseSuccessfulNotification, object: nil)
      }
    }
  }

  func handleRestoredState(for transaction: SKPaymentTransaction, in queue: SKPaymentQueue) {
    print("Purchase restored for product id: \(transaction.payment.productIdentifier)")
    queue.finishTransaction(transaction)
    SubscriptionService.shared.uploadReceipt { (success) in
      DispatchQueue.main.async {
        NotificationCenter.default.post(name: SubscriptionService.restoreSuccessfulNotification, object: nil)
      }
    }
  }

  func handleFailedState(for transaction: SKPaymentTransaction, in queue: SKPaymentQueue) {
    print("Purchase failed for product id: \(transaction.payment.productIdentifier)")
  }

  func handleDeferredState(for transaction: SKPaymentTransaction, in queue: SKPaymentQueue) {
    print("Purchase deferred for product id: \(transaction.payment.productIdentifier)")
  }
}

最佳答案

尽管从技术上讲,您可以验证应用程序的收据并在程序每次运行时重新处理每个IAP,但不会在用户每次启动应用程序时收到有关购买的通知。看来效率低下。您的应用应仅跟踪购买时的购买情况。

如果该应用曾经被删除并重新安装,或者用户将其安装在另一台设备上,则应提供“还原应用内购买”功能,以刷新应用收据并进行验证。

关于ios - Storekit和处理已购买IAP的用户,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47763691/

10-14 20:16