Storekit和处理已购买IAP的用户

时间:2017-12-12 00:40:24

标签: ios swift in-app-purchase subscription storekit

我正在关注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)")
  }
}

1 个答案:

答案 0 :(得分:0)

每次用户启动应用时,您都不会收到购买通知,但从技术上讲,您可以在每次程序运行时验证应用收据并重新处理每个IAP。这似乎效率低下。您的应用应该只跟踪购买时购买的内容。

如果应用程序被删除并重新安装,或者用户将其安装在其他设备上,则应提供“恢复应用程序内购买”功能,刷新应用程序收据并对其进行验证。